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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 self._device = device | 246 self._device = device |
247 self._logcat = None | 247 self._logcat = None |
248 self.logcat_process = None | 248 self.logcat_process = None |
249 self._logcat_tmpoutfile = None | 249 self._logcat_tmpoutfile = None |
250 self._pushed_files = [] | 250 self._pushed_files = [] |
251 self._device_utc_offset = None | 251 self._device_utc_offset = None |
252 self._potential_push_size = 0 | 252 self._potential_push_size = 0 |
253 self._actual_push_size = 0 | 253 self._actual_push_size = 0 |
254 self._external_storage = '' | 254 self._external_storage = '' |
255 self._util_wrapper = '' | 255 self._util_wrapper = '' |
256 self._push_if_needed_cache = {} | |
256 | 257 |
257 def _LogShell(self, cmd): | 258 def _LogShell(self, cmd): |
258 """Logs the adb shell command.""" | 259 """Logs the adb shell command.""" |
259 if self._device: | 260 if self._device: |
260 device_repr = self._device[-4:] | 261 device_repr = self._device[-4:] |
261 else: | 262 else: |
262 device_repr = '????' | 263 device_repr = '????' |
263 logging.info('[%s]> %s', device_repr, cmd) | 264 logging.info('[%s]> %s', device_repr, cmd) |
264 | 265 |
265 def Adb(self): | 266 def Adb(self): |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 """Pushes |host_path| to |device_path|. | 911 """Pushes |host_path| to |device_path|. |
911 | 912 |
912 Works for files and directories. This method skips copying any paths in | 913 Works for files and directories. This method skips copying any paths in |
913 |test_data_paths| that already exist on the device with the same hash. | 914 |test_data_paths| that already exist on the device with the same hash. |
914 | 915 |
915 All pushed files can be removed by calling RemovePushedFiles(). | 916 All pushed files can be removed by calling RemovePushedFiles(). |
916 """ | 917 """ |
917 MAX_INDIVIDUAL_PUSHES = 50 | 918 MAX_INDIVIDUAL_PUSHES = 50 |
918 assert os.path.exists(host_path), 'Local path not found %s' % host_path | 919 assert os.path.exists(host_path), 'Local path not found %s' % host_path |
919 | 920 |
921 # See if the file on the host changed since the last push (if any) and | |
922 # return early if it didn't. Note that this shortcut assumes that the tests | |
923 # on the device don't modify the files. | |
924 if not os.path.isdir(host_path): | |
925 if host_path in self._push_if_needed_cache: | |
926 host_path_mtime = self._push_if_needed_cache[host_path] | |
927 if host_path_mtime == os.stat(host_path).st_mtime: | |
928 return | |
929 | |
920 def GetHostSize(path): | 930 def GetHostSize(path): |
921 return int(cmd_helper.GetCmdOutput(['du', '-sb', path]).split()[0]) | 931 return int(cmd_helper.GetCmdOutput(['du', '-sb', path]).split()[0]) |
922 | 932 |
923 size = GetHostSize(host_path) | 933 size = GetHostSize(host_path) |
924 self._pushed_files.append(device_path) | 934 self._pushed_files.append(device_path) |
925 self._potential_push_size += size | 935 self._potential_push_size += size |
926 | 936 |
927 changed_files = self.GetFilesChanged(host_path, device_path) | 937 changed_files = self.GetFilesChanged(host_path, device_path) |
928 logging.info('Found %d files that need to be pushed to %s', | 938 logging.info('Found %d files that need to be pushed to %s', |
929 len(changed_files), device_path) | 939 len(changed_files), device_path) |
930 if not changed_files: | 940 if not changed_files: |
931 return | 941 return |
932 | 942 |
933 def Push(host, device): | 943 def Push(host, device): |
934 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout | 944 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout |
935 # of 60 seconds which isn't sufficient for a lot of users of this method. | 945 # of 60 seconds which isn't sufficient for a lot of users of this method. |
936 push_command = 'push %s %s' % (host, device) | 946 push_command = 'push %s %s' % (host, device) |
937 self._LogShell(push_command) | 947 self._LogShell(push_command) |
938 | 948 |
939 # Retry push with increasing backoff if the device is busy. | 949 # Retry push with increasing backoff if the device is busy. |
940 retry = 0 | 950 retry = 0 |
941 while True: | 951 while True: |
942 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) | 952 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) |
943 if _HasAdbPushSucceeded(output): | 953 if _HasAdbPushSucceeded(output): |
954 if not os.path.isdir(host_path): | |
craigdh
2013/12/10 19:23:32
If we're only doing this for single files, then in
| |
955 self._push_if_needed_cache[host] = os.stat(host).st_mtime | |
944 return | 956 return |
945 if retry < 3: | 957 if retry < 3: |
946 retry += 1 | 958 retry += 1 |
947 wait_time = 5 * retry | 959 wait_time = 5 * retry |
948 logging.error('Push failed, retrying in %d seconds: %s' % | 960 logging.error('Push failed, retrying in %d seconds: %s' % |
949 (wait_time, output)) | 961 (wait_time, output)) |
950 time.sleep(wait_time) | 962 time.sleep(wait_time) |
951 else: | 963 else: |
952 raise Exception('Push failed: %s' % output) | 964 raise Exception('Push failed: %s' % output) |
953 | 965 |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1713 """ | 1725 """ |
1714 def __init__(self, output): | 1726 def __init__(self, output): |
1715 self._output = output | 1727 self._output = output |
1716 | 1728 |
1717 def write(self, data): | 1729 def write(self, data): |
1718 data = data.replace('\r\r\n', '\n') | 1730 data = data.replace('\r\r\n', '\n') |
1719 self._output.write(data) | 1731 self._output.write(data) |
1720 | 1732 |
1721 def flush(self): | 1733 def flush(self): |
1722 self._output.flush() | 1734 self._output.flush() |
OLD | NEW |