OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Provisions Android devices with settings required for bots. | 7 """Provisions Android devices with settings required for bots. |
8 | 8 |
9 Usage: | 9 Usage: |
10 ./provision_devices.py [-d <device serial number>] | 10 ./provision_devices.py [-d <device serial number>] |
11 """ | 11 """ |
12 | 12 |
13 import argparse | 13 import argparse |
14 import datetime | 14 import datetime |
15 import json | 15 import json |
16 import logging | 16 import logging |
17 import os | 17 import os |
18 import posixpath | 18 import posixpath |
19 import re | 19 import re |
20 import subprocess | 20 import subprocess |
21 import sys | 21 import sys |
22 import time | 22 import time |
23 | 23 |
24 from devil.android import battery_utils | 24 from devil.android import battery_utils |
25 from devil.android import device_blacklist | 25 from devil.android import device_blacklist |
26 from devil.android import device_errors | 26 from devil.android import device_errors |
27 from devil.android import device_temp_file | 27 from devil.android import device_temp_file |
28 from devil.android import device_utils | 28 from devil.android import device_utils |
29 from devil.android.sdk import keyevent | |
29 from devil.android.sdk import version_codes | 30 from devil.android.sdk import version_codes |
30 from devil.utils import run_tests_helper | 31 from devil.utils import run_tests_helper |
31 from devil.utils import timeout_retry | 32 from devil.utils import timeout_retry |
32 from pylib import constants | 33 from pylib import constants |
33 from pylib import device_settings | 34 from pylib import device_settings |
34 | 35 |
35 _SYSTEM_WEBVIEW_PATHS = ['/system/app/webview', '/system/app/WebViewGoogle'] | 36 _SYSTEM_WEBVIEW_PATHS = ['/system/app/webview', '/system/app/WebViewGoogle'] |
36 _CHROME_PACKAGE_REGEX = re.compile('.*chrom.*') | 37 _CHROME_PACKAGE_REGEX = re.compile('.*chrom.*') |
37 _TOMBSTONE_REGEX = re.compile('tombstone.*') | 38 _TOMBSTONE_REGEX = re.compile('tombstone.*') |
38 | 39 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 except device_errors.CommandTimeoutError: | 97 except device_errors.CommandTimeoutError: |
97 logging.error('Device did not finish booting. Will try to reboot.') | 98 logging.error('Device did not finish booting. Will try to reboot.') |
98 device.Reboot(timeout=reboot_timeout) | 99 device.Reboot(timeout=reboot_timeout) |
99 phase_func(device, options) | 100 phase_func(device, options) |
100 if reboot: | 101 if reboot: |
101 device.Reboot(False, retries=0) | 102 device.Reboot(False, retries=0) |
102 device.adb.WaitForDevice() | 103 device.adb.WaitForDevice() |
103 | 104 |
104 try: | 105 try: |
105 if should_run_phase(_PHASES.WIPE): | 106 if should_run_phase(_PHASES.WIPE): |
106 if options.chrome_specific_wipe: | 107 if device.IsUserBuild(): |
jbudorick
2015/11/21 02:37:13
This shouldn't preempt the chrome-specific wipe, w
bpastene
2015/11/23 20:01:50
Not entirely. I moved what I could into an if_user
| |
108 logging.warning('Cannot wipe data in user builds.') | |
109 elif options.chrome_specific_wipe: | |
107 run_phase(WipeChromeData) | 110 run_phase(WipeChromeData) |
108 else: | 111 else: |
109 run_phase(WipeDevice) | 112 run_phase(WipeDevice) |
110 | 113 |
111 if should_run_phase(_PHASES.PROPERTIES): | 114 if should_run_phase(_PHASES.PROPERTIES): |
112 run_phase(SetProperties) | 115 run_phase(SetProperties) |
113 | 116 |
114 if should_run_phase(_PHASES.FINISH): | 117 if should_run_phase(_PHASES.FINISH): |
115 run_phase(FinishProvisioning, reboot=False) | 118 run_phase(FinishProvisioning, reboot=False) |
116 | 119 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE], | 242 device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE], |
240 as_root=True, check_return=True) | 243 as_root=True, check_return=True) |
241 | 244 |
242 | 245 |
243 def SetProperties(device, options): | 246 def SetProperties(device, options): |
244 try: | 247 try: |
245 device.EnableRoot() | 248 device.EnableRoot() |
246 except device_errors.CommandFailedError as e: | 249 except device_errors.CommandFailedError as e: |
247 logging.warning(str(e)) | 250 logging.warning(str(e)) |
248 | 251 |
249 _ConfigureLocalProperties(device, options.enable_java_debug) | 252 if not device.IsUserBuild(): |
253 _ConfigureLocalProperties(device, options.enable_java_debug) | |
254 else: | |
255 logging.warning('Cannot configure properties in user builds.') | |
250 device_settings.ConfigureContentSettings( | 256 device_settings.ConfigureContentSettings( |
251 device, device_settings.DETERMINISTIC_DEVICE_SETTINGS) | 257 device, device_settings.DETERMINISTIC_DEVICE_SETTINGS) |
252 if options.disable_location: | 258 if options.disable_location: |
253 device_settings.ConfigureContentSettings( | 259 device_settings.ConfigureContentSettings( |
254 device, device_settings.DISABLE_LOCATION_SETTINGS) | 260 device, device_settings.DISABLE_LOCATION_SETTINGS) |
255 else: | 261 else: |
256 device_settings.ConfigureContentSettings( | 262 device_settings.ConfigureContentSettings( |
257 device, device_settings.ENABLE_LOCATION_SETTINGS) | 263 device, device_settings.ENABLE_LOCATION_SETTINGS) |
258 | 264 |
259 if options.disable_mock_location: | 265 if options.disable_mock_location: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 '\n'.join(local_props), as_root=True) | 310 '\n'.join(local_props), as_root=True) |
305 # Android will not respect the local props file if it is world writable. | 311 # Android will not respect the local props file if it is world writable. |
306 device.RunShellCommand( | 312 device.RunShellCommand( |
307 ['chmod', '644', device.LOCAL_PROPERTIES_PATH], | 313 ['chmod', '644', device.LOCAL_PROPERTIES_PATH], |
308 as_root=True, check_return=True) | 314 as_root=True, check_return=True) |
309 except device_errors.CommandFailedError: | 315 except device_errors.CommandFailedError: |
310 logging.exception('Failed to configure local properties.') | 316 logging.exception('Failed to configure local properties.') |
311 | 317 |
312 | 318 |
313 def FinishProvisioning(device, options): | 319 def FinishProvisioning(device, options): |
320 # The lockscreen can't be disabled on user builds, so send a keyevent | |
321 # to unlock it. | |
322 if device.IsUserBuild(): | |
323 device.SendKeyEvent(keyevent.KEYCODE_MENU) | |
324 | |
314 if options.min_battery_level is not None: | 325 if options.min_battery_level is not None: |
315 try: | 326 try: |
316 battery = battery_utils.BatteryUtils(device) | 327 battery = battery_utils.BatteryUtils(device) |
317 battery.ChargeDeviceToLevel(options.min_battery_level) | 328 battery.ChargeDeviceToLevel(options.min_battery_level) |
318 except device_errors.CommandFailedError: | 329 except device_errors.CommandFailedError: |
319 logging.exception('Unable to charge device to specified level.') | 330 logging.exception('Unable to charge device to specified level.') |
320 | 331 |
321 if options.max_battery_temp is not None: | 332 if options.max_battery_temp is not None: |
322 try: | 333 try: |
323 battery = battery_utils.BatteryUtils(device) | 334 battery = battery_utils.BatteryUtils(device) |
(...skipping 20 matching lines...) Expand all Loading... | |
344 tdelta = (correct_time - device_time).seconds | 355 tdelta = (correct_time - device_time).seconds |
345 if tdelta <= 1: | 356 if tdelta <= 1: |
346 logging.info('Date/time successfully set on %s', device) | 357 logging.info('Date/time successfully set on %s', device) |
347 return True | 358 return True |
348 else: | 359 else: |
349 logging.error('Date mismatch. Device: %s Correct: %s', | 360 logging.error('Date mismatch. Device: %s Correct: %s', |
350 device_time.isoformat(), correct_time.isoformat()) | 361 device_time.isoformat(), correct_time.isoformat()) |
351 return False | 362 return False |
352 | 363 |
353 # Sometimes the date is not set correctly on the devices. Retry on failure. | 364 # Sometimes the date is not set correctly on the devices. Retry on failure. |
354 if not timeout_retry.WaitFor(_set_and_verify_date, wait_period=1, | 365 # TODO(bpastene): Figure out how to set the date & time on user builds. |
355 max_tries=2): | 366 if not device.IsUserBuild() and not timeout_retry.WaitFor( |
jbudorick
2015/11/21 02:37:13
nit: since this is going to be changed when you fi
bpastene
2015/11/23 20:01:50
Done.
| |
367 _set_and_verify_date, wait_period=1, max_tries=2): | |
356 raise device_errors.CommandFailedError( | 368 raise device_errors.CommandFailedError( |
357 'Failed to set date & time.', device_serial=str(device)) | 369 'Failed to set date & time.', device_serial=str(device)) |
358 | 370 |
359 props = device.RunShellCommand('getprop', check_return=True) | 371 props = device.RunShellCommand('getprop', check_return=True) |
360 for prop in props: | 372 for prop in props: |
361 logging.info(' %s', prop) | 373 logging.info(' %s', prop) |
362 if options.auto_reconnect: | 374 if options.auto_reconnect: |
363 _PushAndLaunchAdbReboot(device, options.target) | 375 _PushAndLaunchAdbReboot(device, options.target) |
364 | 376 |
365 | 377 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
486 args = parser.parse_args() | 498 args = parser.parse_args() |
487 constants.SetBuildType(args.target) | 499 constants.SetBuildType(args.target) |
488 | 500 |
489 run_tests_helper.SetLogLevel(args.verbose) | 501 run_tests_helper.SetLogLevel(args.verbose) |
490 | 502 |
491 return ProvisionDevices(args) | 503 return ProvisionDevices(args) |
492 | 504 |
493 | 505 |
494 if __name__ == '__main__': | 506 if __name__ == '__main__': |
495 sys.exit(main()) | 507 sys.exit(main()) |
OLD | NEW |