1# Copyright 2017 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6import logging
7
8from devil import base_error
9from devil.android import device_errors
10
11logger = logging.getLogger(__name__)
12
13
14def RetryOnSystemCrash(f, device, retries=3):
15  """Retries the given function on a device crash.
16
17  If the provided function fails with a DeviceUnreachableError, this will wait
18  for the device to come back online, then retry the function.
19
20  Note that this uses the same retry scheme as timeout_retry.Run.
21
22  Args:
23    f: a unary callable that takes an instance of device_utils.DeviceUtils.
24    device: an instance of device_utils.DeviceUtils.
25    retries: the number of retries.
26  Returns:
27    Whatever f returns.
28  """
29  num_try = 1
30  while True:
31    try:
32      return f(device)
33    except device_errors.DeviceUnreachableError:
34      if num_try > retries:
35        logger.error('%d consecutive device crashes. No longer retrying.',
36                      num_try)
37        raise
38      try:
39        logger.warning('Device is unreachable. Waiting for recovery...')
40        device.WaitUntilFullyBooted()
41      except base_error.BaseError:
42        logger.exception('Device never recovered. X(')
43    num_try += 1
44