| 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>] |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 with open(args.output_device_blacklist, 'w') as f: | 74 with open(args.output_device_blacklist, 'w') as f: |
| 75 json.dump(blacklisted_devices, f) | 75 json.dump(blacklisted_devices, f) |
| 76 if all(d in blacklisted_devices for d in devices): | 76 if all(d in blacklisted_devices for d in devices): |
| 77 raise device_errors.NoDevicesError | 77 raise device_errors.NoDevicesError |
| 78 return 0 | 78 return 0 |
| 79 | 79 |
| 80 | 80 |
| 81 def ProvisionDevice(device, blacklist, options): | 81 def ProvisionDevice(device, blacklist, options): |
| 82 if options.reboot_timeout: | 82 if options.reboot_timeout: |
| 83 reboot_timeout = options.reboot_timeout | 83 reboot_timeout = options.reboot_timeout |
| 84 elif (device.build_version_sdk >= version_codes.LOLLIPOP): | 84 elif device.build_version_sdk >= version_codes.LOLLIPOP: |
| 85 reboot_timeout = _DEFAULT_TIMEOUTS.LOLLIPOP | 85 reboot_timeout = _DEFAULT_TIMEOUTS.LOLLIPOP |
| 86 else: | 86 else: |
| 87 reboot_timeout = _DEFAULT_TIMEOUTS.PRE_LOLLIPOP | 87 reboot_timeout = _DEFAULT_TIMEOUTS.PRE_LOLLIPOP |
| 88 | 88 |
| 89 def should_run_phase(phase_name): | 89 def should_run_phase(phase_name): |
| 90 return not options.phases or phase_name in options.phases | 90 return not options.phases or phase_name in options.phases |
| 91 | 91 |
| 92 def run_phase(phase_func, reboot=True): | 92 def run_phase(phase_func, reboot=True): |
| 93 try: | 93 try: |
| 94 device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0) | 94 device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0) |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 device.adb.WaitForDevice() | 188 device.adb.WaitForDevice() |
| 189 | 189 |
| 190 if device_authorized: | 190 if device_authorized: |
| 191 adb_keys_set = set(adb_keys) | 191 adb_keys_set = set(adb_keys) |
| 192 for adb_key_file in options.adb_key_files or []: | 192 for adb_key_file in options.adb_key_files or []: |
| 193 try: | 193 try: |
| 194 with open(adb_key_file, 'r') as f: | 194 with open(adb_key_file, 'r') as f: |
| 195 adb_public_keys = f.readlines() | 195 adb_public_keys = f.readlines() |
| 196 adb_keys_set.update(adb_public_keys) | 196 adb_keys_set.update(adb_public_keys) |
| 197 except IOError: | 197 except IOError: |
| 198 logging.warning('Unable to find adb keys file %s.' % adb_key_file) | 198 logging.warning('Unable to find adb keys file %s.', adb_key_file) |
| 199 _WriteAdbKeysFile(device, '\n'.join(adb_keys_set)) | 199 _WriteAdbKeysFile(device, '\n'.join(adb_keys_set)) |
| 200 except device_errors.CommandFailedError: | 200 except device_errors.CommandFailedError: |
| 201 logging.exception('Possible failure while wiping the device. ' | 201 logging.exception('Possible failure while wiping the device. ' |
| 202 'Attempting to continue.') | 202 'Attempting to continue.') |
| 203 | 203 |
| 204 | 204 |
| 205 def _WriteAdbKeysFile(device, adb_keys_string): | 205 def _WriteAdbKeysFile(device, adb_keys_string): |
| 206 dir_path = posixpath.dirname(constants.ADB_KEYS_FILE) | 206 dir_path = posixpath.dirname(constants.ADB_KEYS_FILE) |
| 207 device.RunShellCommand(['mkdir', '-p', dir_path], | 207 device.RunShellCommand(['mkdir', '-p', dir_path], |
| 208 as_root=True, check_return=True) | 208 as_root=True, check_return=True) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 logging.exception('Unable to charge device to specified level.') | 292 logging.exception('Unable to charge device to specified level.') |
| 293 | 293 |
| 294 if options.max_battery_temp is not None: | 294 if options.max_battery_temp is not None: |
| 295 try: | 295 try: |
| 296 battery = battery_utils.BatteryUtils(device) | 296 battery = battery_utils.BatteryUtils(device) |
| 297 battery.LetBatteryCoolToTemperature(options.max_battery_temp) | 297 battery.LetBatteryCoolToTemperature(options.max_battery_temp) |
| 298 except device_errors.CommandFailedError: | 298 except device_errors.CommandFailedError: |
| 299 logging.exception('Unable to let battery cool to specified temperature.') | 299 logging.exception('Unable to let battery cool to specified temperature.') |
| 300 | 300 |
| 301 def _set_and_verify_date(): | 301 def _set_and_verify_date(): |
| 302 if (device.build_version_sdk >= version_codes.MARSHMALLOW): | 302 if device.build_version_sdk >= version_codes.MARSHMALLOW: |
| 303 date_format = '%m%d%H%M%Y.%S' | 303 date_format = '%m%d%H%M%Y.%S' |
| 304 set_date_command = ['date'] | 304 set_date_command = ['date'] |
| 305 else: | 305 else: |
| 306 date_format = '%Y%m%d.%H%M%S' | 306 date_format = '%Y%m%d.%H%M%S' |
| 307 set_date_command = ['date', '-s'] | 307 set_date_command = ['date', '-s'] |
| 308 strgmtime = time.strftime(date_format, time.gmtime()) | 308 strgmtime = time.strftime(date_format, time.gmtime()) |
| 309 set_date_command.append(strgmtime) | 309 set_date_command.append(strgmtime) |
| 310 device.RunShellCommand(set_date_command, as_root=True, check_return=True) | 310 device.RunShellCommand(set_date_command, as_root=True, check_return=True) |
| 311 | 311 |
| 312 device_time = device.RunShellCommand( | 312 device_time = device.RunShellCommand( |
| 313 ['date', '+"%Y%m%d.%H%M%S"'], as_root=True, | 313 ['date', '+"%Y%m%d.%H%M%S"'], as_root=True, |
| 314 single_line=True).replace('"', '') | 314 single_line=True).replace('"', '') |
| 315 device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S") | 315 device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S") |
| 316 correct_time = datetime.datetime.strptime(strgmtime, date_format) | 316 correct_time = datetime.datetime.strptime(strgmtime, date_format) |
| 317 tdelta = (correct_time - device_time).seconds | 317 tdelta = (correct_time - device_time).seconds |
| 318 if tdelta <= 1: | 318 if tdelta <= 1: |
| 319 logging.info('Date/time successfully set on %s', device) | 319 logging.info('Date/time successfully set on %s', device) |
| 320 return True | 320 return True |
| 321 else: | 321 else: |
| 322 return False | 322 return False |
| 323 | 323 |
| 324 # Sometimes the date is not set correctly on the devices. Retry on failure. | 324 # Sometimes the date is not set correctly on the devices. Retry on failure. |
| 325 if not timeout_retry.WaitFor(_set_and_verify_date, wait_period=1, | 325 if not timeout_retry.WaitFor(_set_and_verify_date, wait_period=1, |
| 326 max_tries=2): | 326 max_tries=2): |
| 327 raise device_errors.CommandFailedError( | 327 raise device_errors.CommandFailedError( |
| 328 'Failed to set date & time.', device_serial=str(device)) | 328 'Failed to set date & time.', device_serial=str(device)) |
| 329 | 329 |
| 330 props = device.RunShellCommand('getprop', check_return=True) | 330 props = device.RunShellCommand('getprop', check_return=True) |
| 331 for prop in props: | 331 for prop in props: |
| 332 logging.info(' %s' % prop) | 332 logging.info(' %s', prop) |
| 333 if options.auto_reconnect: | 333 if options.auto_reconnect: |
| 334 _PushAndLaunchAdbReboot(device, options.target) | 334 _PushAndLaunchAdbReboot(device, options.target) |
| 335 | 335 |
| 336 | 336 |
| 337 def _WipeUnderDirIfMatch(device, path, pattern, app_to_keep=None): | 337 def _WipeUnderDirIfMatch(device, path, pattern, app_to_keep=None): |
| 338 ls_result = device.Ls(path) | 338 ls_result = device.Ls(path) |
| 339 for (content, _) in ls_result: | 339 for (content, _) in ls_result: |
| 340 if pattern.match(content): | 340 if pattern.match(content): |
| 341 if content != app_to_keep: | 341 if content != app_to_keep: |
| 342 _WipeFileOrDir(device, path + content) | 342 _WipeFileOrDir(device, path + content) |
| 343 | 343 |
| 344 | 344 |
| 345 def _WipeFileOrDir(device, path): | 345 def _WipeFileOrDir(device, path): |
| 346 if device.PathExists(path): | 346 if device.PathExists(path): |
| 347 device.RunShellCommand(['rm', '-rf', path], check_return=True) | 347 device.RunShellCommand(['rm', '-rf', path], check_return=True) |
| 348 | 348 |
| 349 | 349 |
| 350 def _PushAndLaunchAdbReboot(device, target): | 350 def _PushAndLaunchAdbReboot(device, target): |
| 351 """Pushes and launches the adb_reboot binary on the device. | 351 """Pushes and launches the adb_reboot binary on the device. |
| 352 | 352 |
| 353 Arguments: | 353 Arguments: |
| 354 device: The DeviceUtils instance for the device to which the adb_reboot | 354 device: The DeviceUtils instance for the device to which the adb_reboot |
| 355 binary should be pushed. | 355 binary should be pushed. |
| 356 target: The build target (example, Debug or Release) which helps in | 356 target: The build target (example, Debug or Release) which helps in |
| 357 locating the adb_reboot binary. | 357 locating the adb_reboot binary. |
| 358 """ | 358 """ |
| 359 logging.info('Will push and launch adb_reboot on %s' % str(device)) | 359 logging.info('Will push and launch adb_reboot on %s', str(device)) |
| 360 # Kill if adb_reboot is already running. | 360 # Kill if adb_reboot is already running. |
| 361 device.KillAll('adb_reboot', blocking=True, timeout=2, quiet=True) | 361 device.KillAll('adb_reboot', blocking=True, timeout=2, quiet=True) |
| 362 # Push adb_reboot | 362 # Push adb_reboot |
| 363 logging.info(' Pushing adb_reboot ...') | 363 logging.info(' Pushing adb_reboot ...') |
| 364 adb_reboot = os.path.join(constants.DIR_SOURCE_ROOT, | 364 adb_reboot = os.path.join(constants.DIR_SOURCE_ROOT, |
| 365 'out/%s/adb_reboot' % target) | 365 'out/%s/adb_reboot' % target) |
| 366 device.PushChangedFiles([(adb_reboot, '/data/local/tmp/')]) | 366 device.PushChangedFiles([(adb_reboot, '/data/local/tmp/')]) |
| 367 # Launch adb_reboot | 367 # Launch adb_reboot |
| 368 logging.info(' Launching adb_reboot ...') | 368 logging.info(' Launching adb_reboot ...') |
| 369 device.RunShellCommand( | 369 device.RunShellCommand( |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 args = parser.parse_args() | 450 args = parser.parse_args() |
| 451 constants.SetBuildType(args.target) | 451 constants.SetBuildType(args.target) |
| 452 | 452 |
| 453 run_tests_helper.SetLogLevel(args.verbose) | 453 run_tests_helper.SetLogLevel(args.verbose) |
| 454 | 454 |
| 455 return ProvisionDevices(args) | 455 return ProvisionDevices(args) |
| 456 | 456 |
| 457 | 457 |
| 458 if __name__ == '__main__': | 458 if __name__ == '__main__': |
| 459 sys.exit(main()) | 459 sys.exit(main()) |
| OLD | NEW |