OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Provides an interface to communicate with the device via the adb command. | 5 """Provides an interface to communicate with the device via the adb command. |
6 | 6 |
7 Assumes adb binary is currently on system path. | 7 Assumes adb binary is currently on system path. |
8 """ | 8 """ |
9 | 9 |
10 import collections | 10 import collections |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 self.logcat_process = None | 253 self.logcat_process = None |
254 self._logcat_tmpoutfile = None | 254 self._logcat_tmpoutfile = None |
255 self._pushed_files = [] | 255 self._pushed_files = [] |
256 self._device_utc_offset = None | 256 self._device_utc_offset = None |
257 self._potential_push_size = 0 | 257 self._potential_push_size = 0 |
258 self._actual_push_size = 0 | 258 self._actual_push_size = 0 |
259 self._external_storage = '' | 259 self._external_storage = '' |
260 self._util_wrapper = '' | 260 self._util_wrapper = '' |
261 self._api_strict_mode = api_strict_mode | 261 self._api_strict_mode = api_strict_mode |
262 self._system_properties = system_properties.SystemProperties(self.Adb()) | 262 self._system_properties = system_properties.SystemProperties(self.Adb()) |
| 263 self._push_if_needed_cache = {} |
263 | 264 |
264 if not self._api_strict_mode: | 265 if not self._api_strict_mode: |
265 logging.warning( | 266 logging.warning( |
266 'API STRICT MODE IS DISABLED.\n' | 267 'API STRICT MODE IS DISABLED.\n' |
267 'It should be enabled as soon as possible as it will eventually ' | 268 'It should be enabled as soon as possible as it will eventually ' |
268 'become the default.') | 269 'become the default.') |
269 | 270 |
270 @property | 271 @property |
271 def system_properties(self): | 272 def system_properties(self): |
272 return self._system_properties | 273 return self._system_properties |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 """Pushes |host_path| to |device_path|. | 959 """Pushes |host_path| to |device_path|. |
959 | 960 |
960 Works for files and directories. This method skips copying any paths in | 961 Works for files and directories. This method skips copying any paths in |
961 |test_data_paths| that already exist on the device with the same hash. | 962 |test_data_paths| that already exist on the device with the same hash. |
962 | 963 |
963 All pushed files can be removed by calling RemovePushedFiles(). | 964 All pushed files can be removed by calling RemovePushedFiles(). |
964 """ | 965 """ |
965 MAX_INDIVIDUAL_PUSHES = 50 | 966 MAX_INDIVIDUAL_PUSHES = 50 |
966 assert os.path.exists(host_path), 'Local path not found %s' % host_path | 967 assert os.path.exists(host_path), 'Local path not found %s' % host_path |
967 | 968 |
| 969 # See if the file on the host changed since the last push (if any) and |
| 970 # return early if it didn't. Note that this shortcut assumes that the tests |
| 971 # on the device don't modify the files. |
| 972 if not os.path.isdir(host_path): |
| 973 if host_path in self._push_if_needed_cache: |
| 974 host_path_mtime = self._push_if_needed_cache[host_path] |
| 975 if host_path_mtime == os.stat(host_path).st_mtime: |
| 976 return |
| 977 |
968 def GetHostSize(path): | 978 def GetHostSize(path): |
969 return int(cmd_helper.GetCmdOutput(['du', '-sb', path]).split()[0]) | 979 return int(cmd_helper.GetCmdOutput(['du', '-sb', path]).split()[0]) |
970 | 980 |
971 size = GetHostSize(host_path) | 981 size = GetHostSize(host_path) |
972 self._pushed_files.append(device_path) | 982 self._pushed_files.append(device_path) |
973 self._potential_push_size += size | 983 self._potential_push_size += size |
974 | 984 |
975 changed_files = self.GetFilesChanged(host_path, device_path) | 985 changed_files = self.GetFilesChanged(host_path, device_path) |
976 logging.info('Found %d files that need to be pushed to %s', | 986 logging.info('Found %d files that need to be pushed to %s', |
977 len(changed_files), device_path) | 987 len(changed_files), device_path) |
978 if not changed_files: | 988 if not changed_files: |
979 return | 989 return |
980 | 990 |
981 def Push(host, device): | 991 def Push(host, device): |
982 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout | 992 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout |
983 # of 60 seconds which isn't sufficient for a lot of users of this method. | 993 # of 60 seconds which isn't sufficient for a lot of users of this method. |
984 push_command = 'push %s %s' % (host, device) | 994 push_command = 'push %s %s' % (host, device) |
985 self._LogShell(push_command) | 995 self._LogShell(push_command) |
986 | 996 |
987 # Retry push with increasing backoff if the device is busy. | 997 # Retry push with increasing backoff if the device is busy. |
988 retry = 0 | 998 retry = 0 |
989 while True: | 999 while True: |
990 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) | 1000 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) |
991 if _HasAdbPushSucceeded(output): | 1001 if _HasAdbPushSucceeded(output): |
| 1002 if not os.path.isdir(host_path): |
| 1003 self._push_if_needed_cache[host] = os.stat(host).st_mtime |
992 return | 1004 return |
993 if retry < 3: | 1005 if retry < 3: |
994 retry += 1 | 1006 retry += 1 |
995 wait_time = 5 * retry | 1007 wait_time = 5 * retry |
996 logging.error('Push failed, retrying in %d seconds: %s' % | 1008 logging.error('Push failed, retrying in %d seconds: %s' % |
997 (wait_time, output)) | 1009 (wait_time, output)) |
998 time.sleep(wait_time) | 1010 time.sleep(wait_time) |
999 else: | 1011 else: |
1000 raise Exception('Push failed: %s' % output) | 1012 raise Exception('Push failed: %s' % output) |
1001 | 1013 |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 """ | 1769 """ |
1758 def __init__(self, output): | 1770 def __init__(self, output): |
1759 self._output = output | 1771 self._output = output |
1760 | 1772 |
1761 def write(self, data): | 1773 def write(self, data): |
1762 data = data.replace('\r\r\n', '\n') | 1774 data = data.replace('\r\r\n', '\n') |
1763 self._output.write(data) | 1775 self._output.write(data) |
1764 | 1776 |
1765 def flush(self): | 1777 def flush(self): |
1766 self._output.flush() | 1778 self._output.flush() |
OLD | NEW |