blob: 428d9b3d50830fbd13cec18b3be1f411ba5c667a [file] [log] [blame]
Peter Wenb51e4542021-06-30 17:42:571#!/usr/bin/env vpython3
[email protected]12f36c82013-03-29 06:21:132#
Avi Drissman73a09d12022-09-08 20:33:383# Copyright 2013 The Chromium Authors
[email protected]12f36c82013-03-29 06:21:134# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Provisions Android devices with settings required for bots.
8
9Usage:
10 ./provision_devices.py [-d <device serial number>]
11"""
12
perezjub205693d2015-01-23 11:55:4213import argparse
navabi4bcff9e2015-08-24 16:41:3114import datetime
mikecaseeb1cfbbe2015-06-29 23:31:2015import json
[email protected]552df572014-02-26 20:31:3516import logging
[email protected]12f36c82013-03-29 06:21:1317import os
navabi00c5fd32015-02-26 22:06:4718import posixpath
[email protected]12f36c82013-03-29 06:21:1319import re
20import subprocess
21import sys
22import time
23
stipdfb2d012016-02-17 18:41:4124# Import _strptime before threaded code. datetime.datetime.strptime is
25# threadsafe except for the initial import of the _strptime module.
26# See crbug.com/584730 and https://bugs.python.org/issue7980.
27import _strptime # pylint: disable=unused-import
28
jbudorick0c2a94a2015-12-04 14:27:4329import devil_chromium
jbudorick061629442015-09-03 18:00:5730from devil.android import battery_utils
John Budorick8b57e602020-09-01 16:57:5031from devil.android import device_denylist
jbudorick061629442015-09-03 18:00:5732from devil.android import device_errors
rnephew4597a222015-09-28 20:59:5733from devil.android import device_temp_file
jbudorick061629442015-09-03 18:00:5734from devil.android import device_utils
bpastene79b86792015-12-10 15:28:5835from devil.android.sdk import keyevent
jbudorickd292c5b2015-09-03 00:40:2136from devil.android.sdk import version_codes
jbudorick78e09f912016-05-16 18:56:1537from devil.constants import exit_codes
jbudorick061629442015-09-03 18:00:5738from devil.utils import run_tests_helper
39from devil.utils import timeout_retry
[email protected]12f36c82013-03-29 06:21:1340from pylib import constants
[email protected]552df572014-02-26 20:31:3541from pylib import device_settings
jbudorickd28554a2016-01-11 16:22:5942from pylib.constants import host_paths
[email protected]12f36c82013-03-29 06:21:1343
perezju39b8fbd62015-07-17 11:06:3944_SYSTEM_WEBVIEW_PATHS = ['/system/app/webview', '/system/app/WebViewGoogle']
mlliu2f87a552015-08-25 18:21:3545_CHROME_PACKAGE_REGEX = re.compile('.*chrom.*')
46_TOMBSTONE_REGEX = re.compile('tombstone.*')
perezju39b8fbd62015-07-17 11:06:3947
48
Yoshisato Yanagisawa9f477792021-12-09 00:00:2549class _DEFAULT_TIMEOUTS:
jbudorickb22b9622015-01-29 00:26:2150 # L can take a while to reboot after a wipe.
51 LOLLIPOP = 600
52 PRE_LOLLIPOP = 180
53
54 HELP_TEXT = '{}s on L, {}s on pre-L'.format(LOLLIPOP, PRE_LOLLIPOP)
55
56
Yoshisato Yanagisawa9f477792021-12-09 00:00:2557class _PHASES:
jbudorick7f46f7bf2015-04-08 22:57:3958 WIPE = 'wipe'
59 PROPERTIES = 'properties'
60 FINISH = 'finish'
61
62 ALL = [WIPE, PROPERTIES, FINISH]
[email protected]7849a332013-07-12 01:40:0963
64
jbudorickdde688fb2015-08-27 03:00:1765def ProvisionDevices(args):
John Budorick8b57e602020-09-01 16:57:5066 denylist = (device_denylist.Denylist(args.denylist_file)
67 if args.denylist_file else None)
68 devices = [
69 d for d in device_utils.DeviceUtils.HealthyDevices(denylist)
Nate Fischer1da733c92021-10-04 19:06:1870 if not args.emulators or d.is_emulator
John Budorick8b57e602020-09-01 16:57:5071 ]
jbudorickdde688fb2015-08-27 03:00:1772 if args.device:
73 devices = [d for d in devices if d == args.device]
yolandyan140462c2015-11-07 02:47:0674 if not devices:
75 raise device_errors.DeviceUnreachableError(args.device)
jbudorick7f46f7bf2015-04-08 22:57:3976 parallel_devices = device_utils.DeviceUtils.parallel(devices)
yolandyan140462c2015-11-07 02:47:0677 if args.emulators:
78 parallel_devices.pMap(SetProperties, args)
79 else:
John Budorick8b57e602020-09-01 16:57:5080 parallel_devices.pMap(ProvisionDevice, denylist, args)
jbudorickdde688fb2015-08-27 03:00:1781 if args.auto_reconnect:
jbudorick7f46f7bf2015-04-08 22:57:3982 _LaunchHostHeartbeat()
John Budorick8b57e602020-09-01 16:57:5083 denylisted_devices = denylist.Read() if denylist else []
84 if args.output_device_denylist:
85 with open(args.output_device_denylist, 'w') as f:
86 json.dump(denylisted_devices, f)
87 if all(d in denylisted_devices for d in devices):
jbudorick7f46f7bf2015-04-08 22:57:3988 raise device_errors.NoDevicesError
89 return 0
[email protected]12f36c82013-03-29 06:21:1390
91
John Budorick8b57e602020-09-01 16:57:5092def ProvisionDevice(device, denylist, options):
jbudorick7f46f7bf2015-04-08 22:57:3993 def should_run_phase(phase_name):
94 return not options.phases or phase_name in options.phases
95
mikecase394193952016-06-10 21:20:0296 def run_phase(phase_func, reboot_timeout, reboot=True):
perezju386e0222015-07-16 15:26:0197 try:
98 device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0)
99 except device_errors.CommandTimeoutError:
100 logging.error('Device did not finish booting. Will try to reboot.')
101 device.Reboot(timeout=reboot_timeout)
jbudorick7f46f7bf2015-04-08 22:57:39102 phase_func(device, options)
103 if reboot:
104 device.Reboot(False, retries=0)
105 device.adb.WaitForDevice()
106
jbudorick9e8fa5da2015-04-09 23:40:25107 try:
mikecase394193952016-06-10 21:20:02108 if options.reboot_timeout:
109 reboot_timeout = options.reboot_timeout
110 elif device.build_version_sdk >= version_codes.LOLLIPOP:
111 reboot_timeout = _DEFAULT_TIMEOUTS.LOLLIPOP
112 else:
113 reboot_timeout = _DEFAULT_TIMEOUTS.PRE_LOLLIPOP
114
jbudorick9e8fa5da2015-04-09 23:40:25115 if should_run_phase(_PHASES.WIPE):
bpastene79b86792015-12-10 15:28:58116 if (options.chrome_specific_wipe or device.IsUserBuild() or
117 device.build_version_sdk >= version_codes.MARSHMALLOW):
mikecase394193952016-06-10 21:20:02118 run_phase(WipeChromeData, reboot_timeout)
mlliu2f87a552015-08-25 18:21:35119 else:
mikecase394193952016-06-10 21:20:02120 run_phase(WipeDevice, reboot_timeout)
jbudorick7f46f7bf2015-04-08 22:57:39121
jbudorick9e8fa5da2015-04-09 23:40:25122 if should_run_phase(_PHASES.PROPERTIES):
mikecase394193952016-06-10 21:20:02123 run_phase(SetProperties, reboot_timeout)
jbudorick7f46f7bf2015-04-08 22:57:39124
jbudorick9e8fa5da2015-04-09 23:40:25125 if should_run_phase(_PHASES.FINISH):
mikecase394193952016-06-10 21:20:02126 run_phase(FinishProvisioning, reboot_timeout, reboot=False)
jbudorick9e8fa5da2015-04-09 23:40:25127
mlliu42dd1692015-09-16 02:16:03128 if options.chrome_specific_wipe:
129 package = "com.google.android.gms"
130 version_name = device.GetApplicationVersion(package)
131 logging.info("Version name for %s is %s", package, version_name)
132
rnephew952bc2a2015-10-10 02:27:11133 CheckExternalStorage(device)
134
jbudorickcd661e4f2015-08-13 19:33:54135 except device_errors.CommandTimeoutError:
John Budorick8b57e602020-09-01 16:57:50136 logging.exception('Timed out waiting for device %s. Adding to denylist.',
jbudorick9e8fa5da2015-04-09 23:40:25137 str(device))
John Budorick8b57e602020-09-01 16:57:50138 if denylist:
139 denylist.Extend([str(device)], reason='provision_timeout')
jbudorick9e8fa5da2015-04-09 23:40:25140
perezju46865bb32017-04-13 12:19:51141 except (device_errors.CommandFailedError,
142 device_errors.DeviceUnreachableError):
John Budorick8b57e602020-09-01 16:57:50143 logging.exception('Failed to provision device %s. Adding to denylist.',
jbudorick9e8fa5da2015-04-09 23:40:25144 str(device))
John Budorick8b57e602020-09-01 16:57:50145 if denylist:
146 denylist.Extend([str(device)], reason='provision_failure')
147
jbudorick7f46f7bf2015-04-08 22:57:39148
rnephew4597a222015-09-28 20:59:57149def CheckExternalStorage(device):
150 """Checks that storage is writable and if not makes it writable.
151
152 Arguments:
153 device: The device to check.
154 """
155 try:
156 with device_temp_file.DeviceTempFile(
agrievefc5b96fe2015-10-16 15:34:08157 device.adb, suffix='.sh', dir=device.GetExternalStoragePath()) as f:
158 device.WriteFile(f.name, 'test')
rnephew4597a222015-09-28 20:59:57159 except device_errors.CommandFailedError:
160 logging.info('External storage not writable. Remounting / as RW')
161 device.RunShellCommand(['mount', '-o', 'remount,rw', '/'],
162 check_return=True, as_root=True)
rnephew952bc2a2015-10-10 02:27:11163 device.EnableRoot()
rnephew4597a222015-09-28 20:59:57164 with device_temp_file.DeviceTempFile(
agrievefc5b96fe2015-10-16 15:34:08165 device.adb, suffix='.sh', dir=device.GetExternalStoragePath()) as f:
166 device.WriteFile(f.name, 'test')
jbudorick7f46f7bf2015-04-08 22:57:39167
mlliu2f87a552015-08-25 18:21:35168def WipeChromeData(device, options):
169 """Wipes chrome specific data from device
mlliu44ebcee2015-09-24 07:55:38170
171 (1) uninstall any app whose name matches *chrom*, except
172 com.android.chrome, which is the chrome stable package. Doing so also
173 removes the corresponding dirs under /data/data/ and /data/app/
174 (2) remove any dir under /data/app-lib/ whose name matches *chrom*
175 (3) remove any files under /data/tombstones/ whose name matches "tombstone*"
176 (4) remove /data/local.prop if there is any
177 (5) remove /data/local/chrome-command-line if there is any
178 (6) remove anything under /data/local/.config/ if the dir exists
179 (this is telemetry related)
180 (7) remove anything under /data/local/tmp/
mlliu2f87a552015-08-25 18:21:35181
182 Arguments:
183 device: the device to wipe
184 """
185 if options.skip_wipe:
186 return
187
188 try:
bpastene79b86792015-12-10 15:28:58189 if device.IsUserBuild():
190 _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX,
191 constants.PACKAGE_INFO['chrome_stable'].package)
192 device.RunShellCommand('rm -rf %s/*' % device.GetExternalStoragePath(),
193 check_return=True)
194 device.RunShellCommand('rm -rf /data/local/tmp/*', check_return=True)
195 else:
196 device.EnableRoot()
197 _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX,
198 constants.PACKAGE_INFO['chrome_stable'].package)
199 _WipeUnderDirIfMatch(device, '/data/app-lib/', _CHROME_PACKAGE_REGEX)
200 _WipeUnderDirIfMatch(device, '/data/tombstones/', _TOMBSTONE_REGEX)
mlliu2f87a552015-08-25 18:21:35201
bpastene79b86792015-12-10 15:28:58202 _WipeFileOrDir(device, '/data/local.prop')
203 _WipeFileOrDir(device, '/data/local/chrome-command-line')
204 _WipeFileOrDir(device, '/data/local/.config/')
205 _WipeFileOrDir(device, '/data/local/tmp/')
206 device.RunShellCommand('rm -rf %s/*' % device.GetExternalStoragePath(),
207 check_return=True)
mlliu2f87a552015-08-25 18:21:35208 except device_errors.CommandFailedError:
209 logging.exception('Possible failure while wiping the device. '
210 'Attempting to continue.')
211
212
jbudorick7f46f7bf2015-04-08 22:57:39213def WipeDevice(device, options):
214 """Wipes data from device, keeping only the adb_keys for authorization.
215
216 After wiping data on a device that has been authorized, adb can still
217 communicate with the device, but after reboot the device will need to be
218 re-authorized because the adb keys file is stored in /data/misc/adb/.
219 Thus, adb_keys file is rewritten so the device does not need to be
220 re-authorized.
221
222 Arguments:
223 device: the device to wipe
224 """
225 if options.skip_wipe:
226 return
227
jbudorick7f46f7bf2015-04-08 22:57:39228 try:
jbudorick9e8fa5da2015-04-09 23:40:25229 device.EnableRoot()
230 device_authorized = device.FileExists(constants.ADB_KEYS_FILE)
231 if device_authorized:
232 adb_keys = device.ReadFile(constants.ADB_KEYS_FILE,
233 as_root=True).splitlines()
jbudorick7f46f7bf2015-04-08 22:57:39234 device.RunShellCommand(['wipe', 'data'],
jbudorick809d9aff2015-04-09 16:45:29235 as_root=True, check_return=True)
jbudorick9e8fa5da2015-04-09 23:40:25236 device.adb.WaitForDevice()
237
238 if device_authorized:
239 adb_keys_set = set(adb_keys)
240 for adb_key_file in options.adb_key_files or []:
241 try:
242 with open(adb_key_file, 'r') as f:
243 adb_public_keys = f.readlines()
244 adb_keys_set.update(adb_public_keys)
245 except IOError:
jbudorick58b4d362015-09-08 16:44:59246 logging.warning('Unable to find adb keys file %s.', adb_key_file)
jbudorick9e8fa5da2015-04-09 23:40:25247 _WriteAdbKeysFile(device, '\n'.join(adb_keys_set))
jbudorick7f46f7bf2015-04-08 22:57:39248 except device_errors.CommandFailedError:
249 logging.exception('Possible failure while wiping the device. '
250 'Attempting to continue.')
jbudorick7f46f7bf2015-04-08 22:57:39251
252
253def _WriteAdbKeysFile(device, adb_keys_string):
254 dir_path = posixpath.dirname(constants.ADB_KEYS_FILE)
255 device.RunShellCommand(['mkdir', '-p', dir_path],
256 as_root=True, check_return=True)
257 device.RunShellCommand(['restorecon', dir_path],
258 as_root=True, check_return=True)
259 device.WriteFile(constants.ADB_KEYS_FILE, adb_keys_string, as_root=True)
260 device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE],
261 as_root=True, check_return=True)
262
263
264def SetProperties(device, options):
265 try:
266 device.EnableRoot()
267 except device_errors.CommandFailedError as e:
268 logging.warning(str(e))
269
bpastene79b86792015-12-10 15:28:58270 if not device.IsUserBuild():
271 _ConfigureLocalProperties(device, options.enable_java_debug)
272 else:
273 logging.warning('Cannot configure properties in user builds.')
jbudorick7f46f7bf2015-04-08 22:57:39274 device_settings.ConfigureContentSettings(
275 device, device_settings.DETERMINISTIC_DEVICE_SETTINGS)
276 if options.disable_location:
277 device_settings.ConfigureContentSettings(
278 device, device_settings.DISABLE_LOCATION_SETTINGS)
279 else:
280 device_settings.ConfigureContentSettings(
281 device, device_settings.ENABLE_LOCATION_SETTINGS)
hush252db182015-07-08 21:42:00282
hush4143b7082015-07-09 18:41:11283 if options.disable_mock_location:
hush252db182015-07-08 21:42:00284 device_settings.ConfigureContentSettings(
285 device, device_settings.DISABLE_MOCK_LOCATION_SETTINGS)
hush4143b7082015-07-09 18:41:11286 else:
287 device_settings.ConfigureContentSettings(
288 device, device_settings.ENABLE_MOCK_LOCATION_SETTINGS)
hush252db182015-07-08 21:42:00289
jbudorick7f46f7bf2015-04-08 22:57:39290 device_settings.SetLockScreenSettings(device)
291 if options.disable_network:
292 device_settings.ConfigureContentSettings(
293 device, device_settings.NETWORK_DISABLED_SETTINGS)
perezju154947a2016-08-08 13:59:47294 if device.build_version_sdk >= version_codes.MARSHMALLOW:
295 # Ensure that NFC is also switched off.
296 device.RunShellCommand(['svc', 'nfc', 'disable'],
297 as_root=True, check_return=True)
jbudorick7f46f7bf2015-04-08 22:57:39298
perezjudcc86802015-08-25 18:39:39299 if options.disable_system_chrome:
300 # The system chrome version on the device interferes with some tests.
301 device.RunShellCommand(['pm', 'disable', 'com.android.chrome'],
302 check_return=True)
303
perezju39b8fbd62015-07-17 11:06:39304 if options.remove_system_webview:
yolandyan161d167a2016-05-11 00:52:26305 if any(device.PathExists(p) for p in _SYSTEM_WEBVIEW_PATHS):
306 logging.info('System WebView exists and needs to be removed')
307 if device.HasRoot():
308 # Disabled Marshmallow's Verity security feature
309 if device.build_version_sdk >= version_codes.MARSHMALLOW:
310 device.adb.DisableVerity()
311 device.Reboot()
312 device.WaitUntilFullyBooted()
313 device.EnableRoot()
314
315 # This is required, e.g., to replace the system webview on a device.
316 device.adb.Remount()
317 device.RunShellCommand(['stop'], check_return=True)
318 device.RunShellCommand(['rm', '-rf'] + _SYSTEM_WEBVIEW_PATHS,
319 check_return=True)
320 device.RunShellCommand(['start'], check_return=True)
321 else:
322 logging.warning('Cannot remove system webview from a non-rooted device')
perezju39b8fbd62015-07-17 11:06:39323 else:
yolandyan161d167a2016-05-11 00:52:26324 logging.info('System WebView already removed')
perezju39b8fbd62015-07-17 11:06:39325
bpastene5c7a1902015-12-14 22:18:09326 # Some device types can momentarily disappear after setting properties.
327 device.adb.WaitForDevice()
328
perezju39b8fbd62015-07-17 11:06:39329
jbudorick7f46f7bf2015-04-08 22:57:39330def _ConfigureLocalProperties(device, java_debug=True):
331 """Set standard readonly testing device properties prior to reboot."""
332 local_props = [
333 'persist.sys.usb.config=adb',
334 'ro.monkey=1',
335 'ro.test_harness=1',
336 'ro.audio.silent=1',
337 'ro.setupwizard.mode=DISABLED',
338 ]
339 if java_debug:
jbudorickbfffb22e2015-04-16 14:10:02340 local_props.append(
341 '%s=all' % device_utils.DeviceUtils.JAVA_ASSERT_PROPERTY)
jbudorick7f46f7bf2015-04-08 22:57:39342 local_props.append('debug.checkjni=1')
343 try:
344 device.WriteFile(
jbudorickd292c5b2015-09-03 00:40:21345 device.LOCAL_PROPERTIES_PATH,
jbudorick7f46f7bf2015-04-08 22:57:39346 '\n'.join(local_props), as_root=True)
347 # Android will not respect the local props file if it is world writable.
348 device.RunShellCommand(
jbudorickd292c5b2015-09-03 00:40:21349 ['chmod', '644', device.LOCAL_PROPERTIES_PATH],
jbudorick7f46f7bf2015-04-08 22:57:39350 as_root=True, check_return=True)
jbudorick9e8fa5da2015-04-09 23:40:25351 except device_errors.CommandFailedError:
352 logging.exception('Failed to configure local properties.')
jbudorick7f46f7bf2015-04-08 22:57:39353
354
355def FinishProvisioning(device, options):
bpastene79b86792015-12-10 15:28:58356 # The lockscreen can't be disabled on user builds, so send a keyevent
357 # to unlock it.
358 if device.IsUserBuild():
359 device.SendKeyEvent(keyevent.KEYCODE_MENU)
360
jbudorickf9f6af82015-07-01 17:24:54361 if options.min_battery_level is not None:
rnephew0204d422016-02-11 21:46:36362 battery = battery_utils.BatteryUtils(device)
jbudorickf9f6af82015-07-01 17:24:54363 try:
jbudorickf9f6af82015-07-01 17:24:54364 battery.ChargeDeviceToLevel(options.min_battery_level)
rnephew0204d422016-02-11 21:46:36365 except device_errors.DeviceChargingError:
366 device.Reboot()
367 battery.ChargeDeviceToLevel(options.min_battery_level)
jbudorickf9f6af82015-07-01 17:24:54368
369 if options.max_battery_temp is not None:
370 try:
371 battery = battery_utils.BatteryUtils(device)
372 battery.LetBatteryCoolToTemperature(options.max_battery_temp)
373 except device_errors.CommandFailedError:
374 logging.exception('Unable to let battery cool to specified temperature.')
375
navabi4bcff9e2015-08-24 16:41:31376 def _set_and_verify_date():
jbudorick58b4d362015-09-08 16:44:59377 if device.build_version_sdk >= version_codes.MARSHMALLOW:
jbudorick7f5231e2015-08-27 23:02:39378 date_format = '%m%d%H%M%Y.%S'
jbudorick24b85fd2016-05-14 00:05:06379 set_date_command = ['date', '-u']
jbudorick78e09f912016-05-16 18:56:15380 get_date_command = ['date', '-u']
jbudorick7f5231e2015-08-27 23:02:39381 else:
382 date_format = '%Y%m%d.%H%M%S'
jbudorick78e09f912016-05-16 18:56:15383 set_date_command = ['date', '-s']
384 get_date_command = ['date']
385
386 # TODO(jbudorick): This is wrong on pre-M devices -- get/set are
387 # dealing in local time, but we're setting based on GMT.
jbudorick7f5231e2015-08-27 23:02:39388 strgmtime = time.strftime(date_format, time.gmtime())
389 set_date_command.append(strgmtime)
390 device.RunShellCommand(set_date_command, as_root=True, check_return=True)
navabi4bcff9e2015-08-24 16:41:31391
jbudorick78e09f912016-05-16 18:56:15392 get_date_command.append('+"%Y%m%d.%H%M%S"')
navabi4bcff9e2015-08-24 16:41:31393 device_time = device.RunShellCommand(
jbudorick78e09f912016-05-16 18:56:15394 get_date_command, as_root=True, single_line=True).replace('"', '')
jbudorick7f5231e2015-08-27 23:02:39395 device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
396 correct_time = datetime.datetime.strptime(strgmtime, date_format)
Haiyang Panbb1655a2022-11-07 17:39:09397 tdelta = abs(correct_time - device_time).seconds
navabi4bcff9e2015-08-24 16:41:31398 if tdelta <= 1:
jbudorick7f5231e2015-08-27 23:02:39399 logging.info('Date/time successfully set on %s', device)
navabi4bcff9e2015-08-24 16:41:31400 return True
Yoshisato Yanagisawa0f42f102021-11-30 14:04:37401 logging.error('Date mismatch. Device: %s Correct: %s',
402 device_time.isoformat(), correct_time.isoformat())
403 return False
navabi4bcff9e2015-08-24 16:41:31404
405 # Sometimes the date is not set correctly on the devices. Retry on failure.
bpastene79b86792015-12-10 15:28:58406 if device.IsUserBuild():
407 # TODO(bpastene): Figure out how to set the date & time on user builds.
408 pass
409 else:
410 if not timeout_retry.WaitFor(
411 _set_and_verify_date, wait_period=1, max_tries=2):
412 raise device_errors.CommandFailedError(
413 'Failed to set date & time.', device_serial=str(device))
navabi4bcff9e2015-08-24 16:41:31414
jbudorick9e8fa5da2015-04-09 23:40:25415 props = device.RunShellCommand('getprop', check_return=True)
416 for prop in props:
jbudorick58b4d362015-09-08 16:44:59417 logging.info(' %s', prop)
jbudorick9e8fa5da2015-04-09 23:40:25418 if options.auto_reconnect:
419 _PushAndLaunchAdbReboot(device, options.target)
jbudorick7f46f7bf2015-04-08 22:57:39420
421
mlliu44ebcee2015-09-24 07:55:38422def _UninstallIfMatch(device, pattern, app_to_keep):
423 installed_packages = device.RunShellCommand(['pm', 'list', 'packages'])
bpastene5c7a1902015-12-14 22:18:09424 installed_system_packages = [
425 pkg.split(':')[1] for pkg in device.RunShellCommand(['pm', 'list',
426 'packages', '-s'])]
mlliu44ebcee2015-09-24 07:55:38427 for package_output in installed_packages:
428 package = package_output.split(":")[1]
429 if pattern.match(package) and not package == app_to_keep:
bpastene5c7a1902015-12-14 22:18:09430 if not device.IsUserBuild() or package not in installed_system_packages:
431 device.Uninstall(package)
mlliu44ebcee2015-09-24 07:55:38432
433
434def _WipeUnderDirIfMatch(device, path, pattern):
perezju5ad37222016-06-09 16:35:04435 for filename in device.ListDirectory(path):
436 if pattern.match(filename):
437 _WipeFileOrDir(device, posixpath.join(path, filename))
mlliu2f87a552015-08-25 18:21:35438
439
440def _WipeFileOrDir(device, path):
441 if device.PathExists(path):
442 device.RunShellCommand(['rm', '-rf', path], check_return=True)
443
444
jbudorick7f46f7bf2015-04-08 22:57:39445def _PushAndLaunchAdbReboot(device, target):
[email protected]c89aae02013-04-06 00:25:19446 """Pushes and launches the adb_reboot binary on the device.
447
448 Arguments:
[email protected]af4457b2014-08-21 04:17:07449 device: The DeviceUtils instance for the device to which the adb_reboot
450 binary should be pushed.
451 target: The build target (example, Debug or Release) which helps in
452 locating the adb_reboot binary.
[email protected]c89aae02013-04-06 00:25:19453 """
jbudorick58b4d362015-09-08 16:44:59454 logging.info('Will push and launch adb_reboot on %s', str(device))
[email protected]af4457b2014-08-21 04:17:07455 # Kill if adb_reboot is already running.
perezju84436c82015-04-15 10:19:22456 device.KillAll('adb_reboot', blocking=True, timeout=2, quiet=True)
[email protected]af4457b2014-08-21 04:17:07457 # Push adb_reboot
458 logging.info(' Pushing adb_reboot ...')
jbudorickd28554a2016-01-11 16:22:59459 adb_reboot = os.path.join(host_paths.DIR_SOURCE_ROOT,
[email protected]af4457b2014-08-21 04:17:07460 'out/%s/adb_reboot' % target)
jbudorick8c07d892014-10-13 11:39:48461 device.PushChangedFiles([(adb_reboot, '/data/local/tmp/')])
[email protected]af4457b2014-08-21 04:17:07462 # Launch adb_reboot
463 logging.info(' Launching adb_reboot ...')
jbudorick7f46f7bf2015-04-08 22:57:39464 device.RunShellCommand(
aurimas59c81172015-05-11 19:49:51465 ['/data/local/tmp/adb_reboot'],
jbudorick7f46f7bf2015-04-08 22:57:39466 check_return=True)
[email protected]c89aae02013-04-06 00:25:19467
468
jbudorick7f46f7bf2015-04-08 22:57:39469def _LaunchHostHeartbeat():
470 # Kill if existing host_heartbeat
jbudorick809d9aff2015-04-09 16:45:29471 KillHostHeartbeat()
jbudorick7f46f7bf2015-04-08 22:57:39472 # Launch a new host_heartbeat
473 logging.info('Spawning host heartbeat...')
jbudorickd28554a2016-01-11 16:22:59474 subprocess.Popen([os.path.join(host_paths.DIR_SOURCE_ROOT,
jbudorick7f46f7bf2015-04-08 22:57:39475 'build/android/host_heartbeat.py')])
navabi00c5fd32015-02-26 22:06:47476
jbudorick809d9aff2015-04-09 16:45:29477def KillHostHeartbeat():
jbudorick7f46f7bf2015-04-08 22:57:39478 ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
479 stdout, _ = ps.communicate()
480 matches = re.findall('\\n.*host_heartbeat.*', stdout)
481 for match in matches:
482 logging.info('An instance of host heart beart running... will kill')
483 pid = re.findall(r'(\S+)', match)[1]
484 subprocess.call(['kill', str(pid)])
[email protected]12f36c82013-03-29 06:21:13485
perezjub205693d2015-01-23 11:55:42486def main():
perezjub205693d2015-01-23 11:55:42487 # Recommended options on perf bots:
488 # --disable-network
489 # TODO(tonyg): We eventually want network on. However, currently radios
490 # can cause perfbots to drain faster than they charge.
perezju545a9ce2015-02-19 13:14:20491 # --min-battery-level 95
perezjub205693d2015-01-23 11:55:42492 # Some perf bots run benchmarks with USB charging disabled which leads
493 # to gradual draining of the battery. We must wait for a full charge
494 # before starting a run in order to keep the devices online.
[email protected]12f36c82013-03-29 06:21:13495
perezjub205693d2015-01-23 11:55:42496 parser = argparse.ArgumentParser(
497 description='Provision Android devices with settings required for bots.')
498 parser.add_argument('-d', '--device', metavar='SERIAL',
499 help='the serial number of the device to be provisioned'
500 ' (the default is to provision all devices attached)')
jbudorickbe1dd782016-01-12 22:52:25501 parser.add_argument('--adb-path',
502 help='Absolute path to the adb binary to use.')
John Budorick8b57e602020-09-01 16:57:50503 parser.add_argument('--denylist-file', help='Device denylist JSON file.')
jbudorick7f46f7bf2015-04-08 22:57:39504 parser.add_argument('--phase', action='append', choices=_PHASES.ALL,
505 dest='phases',
506 help='Phases of provisioning to run. '
507 '(If omitted, all phases will be run.)')
perezjub205693d2015-01-23 11:55:42508 parser.add_argument('--skip-wipe', action='store_true', default=False,
509 help="don't wipe device data during provisioning")
jbudorickb22b9622015-01-29 00:26:21510 parser.add_argument('--reboot-timeout', metavar='SECS', type=int,
perezjub205693d2015-01-23 11:55:42511 help='when wiping the device, max number of seconds to'
jbudorickb22b9622015-01-29 00:26:21512 ' wait after each reboot '
513 '(default: %s)' % _DEFAULT_TIMEOUTS.HELP_TEXT)
perezju545a9ce2015-02-19 13:14:20514 parser.add_argument('--min-battery-level', type=int, metavar='NUM',
515 help='wait for the device to reach this minimum battery'
516 ' level before trying to continue')
perezjub205693d2015-01-23 11:55:42517 parser.add_argument('--disable-location', action='store_true',
518 help='disable Google location services on devices')
hush4143b7082015-07-09 18:41:11519 parser.add_argument('--disable-mock-location', action='store_true',
520 default=False, help='Set ALLOW_MOCK_LOCATION to false')
perezjub205693d2015-01-23 11:55:42521 parser.add_argument('--disable-network', action='store_true',
perezjub205693d2015-01-23 11:55:42522 help='disable network access on devices')
523 parser.add_argument('--disable-java-debug', action='store_false',
perezju545a9ce2015-02-19 13:14:20524 dest='enable_java_debug', default=True,
perezjub205693d2015-01-23 11:55:42525 help='disable Java property asserts and JNI checking')
perezjudcc86802015-08-25 18:39:39526 parser.add_argument('--disable-system-chrome', action='store_true',
527 help='Disable the system chrome from devices.')
perezju39b8fbd62015-07-17 11:06:39528 parser.add_argument('--remove-system-webview', action='store_true',
529 help='Remove the system webview from devices.')
perezjub205693d2015-01-23 11:55:42530 parser.add_argument('-t', '--target', default='Debug',
531 help='the build target (default: %(default)s)')
532 parser.add_argument('-r', '--auto-reconnect', action='store_true',
533 help='push binary which will reboot the device on adb'
534 ' disconnections')
navabi00c5fd32015-02-26 22:06:47535 parser.add_argument('--adb-key-files', type=str, nargs='+',
536 help='list of adb keys to push to device')
jbudorick7f46f7bf2015-04-08 22:57:39537 parser.add_argument('-v', '--verbose', action='count', default=1,
538 help='Log more information.')
rnephew7ce719b2015-05-07 05:35:54539 parser.add_argument('--max-battery-temp', type=int, metavar='NUM',
540 help='Wait for the battery to have this temp or lower.')
John Budorick8b57e602020-09-01 16:57:50541 parser.add_argument('--output-device-denylist',
542 help='Json file to output the device denylist.')
mlliu2f87a552015-08-25 18:21:35543 parser.add_argument('--chrome-specific-wipe', action='store_true',
544 help='only wipe chrome specific data during provisioning')
yolandyan140462c2015-11-07 02:47:06545 parser.add_argument('--emulators', action='store_true',
546 help='provision only emulators and ignore usb devices')
perezjub205693d2015-01-23 11:55:42547 args = parser.parse_args()
548 constants.SetBuildType(args.target)
549
jbudorick7f46f7bf2015-04-08 22:57:39550 run_tests_helper.SetLogLevel(args.verbose)
551
jbudorick3e0f4b22016-05-28 04:49:47552 devil_chromium.Initialize(adb_path=args.adb_path)
jbudorick0c2a94a2015-12-04 14:27:43553
jbudorick78e09f912016-05-16 18:56:15554 try:
555 return ProvisionDevices(args)
556 except (device_errors.DeviceUnreachableError, device_errors.NoDevicesError):
mikecase371d4042017-01-13 17:09:14557 logging.exception('Unable to provision local devices.')
jbudorick78e09f912016-05-16 18:56:15558 return exit_codes.INFRA
[email protected]12f36c82013-03-29 06:21:13559
560
561if __name__ == '__main__':
perezjub205693d2015-01-23 11:55:42562 sys.exit(main())