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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 os.environ['PATH'] += os.pathsep + adb_dir | 213 os.environ['PATH'] += os.pathsep + adb_dir |
214 self._adb = adb_interface.AdbInterface() | 214 self._adb = adb_interface.AdbInterface() |
215 if device: | 215 if device: |
216 self._adb.SetTargetSerial(device) | 216 self._adb.SetTargetSerial(device) |
217 self._device = device | 217 self._device = device |
218 self._logcat = None | 218 self._logcat = None |
219 self.logcat_process = None | 219 self.logcat_process = None |
220 self._logcat_tmpoutfile = None | 220 self._logcat_tmpoutfile = None |
221 self._pushed_files = [] | 221 self._pushed_files = [] |
222 self._device_utc_offset = None | 222 self._device_utc_offset = None |
| 223 self._potential_push_size = 0 |
| 224 self._actual_push_size = 0 |
223 self._md5sum_build_dir = '' | 225 self._md5sum_build_dir = '' |
224 self._external_storage = '' | 226 self._external_storage = '' |
225 self._util_wrapper = '' | 227 self._util_wrapper = '' |
226 | 228 |
227 def _LogShell(self, cmd): | 229 def _LogShell(self, cmd): |
228 """Logs the adb shell command.""" | 230 """Logs the adb shell command.""" |
229 if self._device: | 231 if self._device: |
230 device_repr = self._device[-4:] | 232 device_repr = self._device[-4:] |
231 else: | 233 else: |
232 device_repr = '????' | 234 device_repr = '????' |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 | 703 |
702 Args: | 704 Args: |
703 local_path: Path (file or directory) on the host. | 705 local_path: Path (file or directory) on the host. |
704 device_path: Path on the device. | 706 device_path: Path on the device. |
705 ignore_paths: If False, both the md5sum and the relative paths/names of | 707 ignore_paths: If False, both the md5sum and the relative paths/names of |
706 files must match. If True, only the md5sum must match. | 708 files must match. If True, only the md5sum must match. |
707 | 709 |
708 Returns: | 710 Returns: |
709 True if the md5sums match. | 711 True if the md5sums match. |
710 """ | 712 """ |
711 assert os.path.exists(local_path), 'Local path not found %s' % local_path | |
712 | |
713 if not self._md5sum_build_dir: | 713 if not self._md5sum_build_dir: |
714 default_build_type = os.environ.get('BUILD_TYPE', 'Debug') | 714 default_build_type = os.environ.get('BUILD_TYPE', 'Debug') |
715 build_dir = '%s/%s/' % ( | 715 build_dir = '%s/%s/' % ( |
716 cmd_helper.OutDirectory().get(), default_build_type) | 716 cmd_helper.OutDirectory().get(), default_build_type) |
717 md5sum_dist_path = '%s/md5sum_dist' % build_dir | 717 md5sum_dist_path = '%s/md5sum_dist' % build_dir |
718 if not os.path.exists(md5sum_dist_path): | 718 if not os.path.exists(md5sum_dist_path): |
719 build_dir = '%s/Release/' % cmd_helper.OutDirectory().get() | 719 build_dir = '%s/Release/' % cmd_helper.OutDirectory().get() |
720 md5sum_dist_path = '%s/md5sum_dist' % build_dir | 720 md5sum_dist_path = '%s/md5sum_dist' % build_dir |
721 assert os.path.exists(md5sum_dist_path), 'Please build md5sum.' | 721 assert os.path.exists(md5sum_dist_path), 'Please build md5sum.' |
722 command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER) | 722 command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER) |
723 assert _HasAdbPushSucceeded(self._adb.SendCommand(command)) | 723 assert _HasAdbPushSucceeded(self._adb.SendCommand(command)) |
724 self._md5sum_build_dir = build_dir | 724 self._md5sum_build_dir = build_dir |
725 | 725 |
726 self._pushed_files.append(device_path) | |
727 hashes_on_device = _ComputeFileListHash( | 726 hashes_on_device = _ComputeFileListHash( |
728 self.RunShellCommand(MD5SUM_LD_LIBRARY_PATH + ' ' + self._util_wrapper + | 727 self.RunShellCommand(MD5SUM_LD_LIBRARY_PATH + ' ' + self._util_wrapper + |
729 ' ' + MD5SUM_DEVICE_PATH + ' ' + device_path)) | 728 ' ' + MD5SUM_DEVICE_PATH + ' ' + device_path)) |
730 assert os.path.exists(local_path), 'Local path not found %s' % local_path | 729 assert os.path.exists(local_path), 'Local path not found %s' % local_path |
731 md5sum_output = cmd_helper.GetCmdOutput( | 730 md5sum_output = cmd_helper.GetCmdOutput( |
732 ['%s/md5sum_bin_host' % self._md5sum_build_dir, local_path]) | 731 ['%s/md5sum_bin_host' % self._md5sum_build_dir, local_path]) |
733 hashes_on_host = _ComputeFileListHash(md5sum_output.splitlines()) | 732 hashes_on_host = _ComputeFileListHash(md5sum_output.splitlines()) |
734 | 733 |
735 if ignore_paths: | 734 if ignore_paths: |
736 hashes_on_device = [h.split()[0] for h in hashes_on_device] | 735 hashes_on_device = [h.split()[0] for h in hashes_on_device] |
737 hashes_on_host = [h.split()[0] for h in hashes_on_host] | 736 hashes_on_host = [h.split()[0] for h in hashes_on_host] |
738 | 737 |
739 return hashes_on_device == hashes_on_host | 738 return hashes_on_device == hashes_on_host |
740 | 739 |
741 def PushIfNeeded(self, local_path, device_path): | 740 def PushIfNeeded(self, local_path, device_path): |
742 """Pushes |local_path| to |device_path|. | 741 """Pushes |local_path| to |device_path|. |
743 | 742 |
744 Works for files and directories. This method skips copying any paths in | 743 Works for files and directories. This method skips copying any paths in |
745 |test_data_paths| that already exist on the device with the same hash. | 744 |test_data_paths| that already exist on the device with the same hash. |
746 | 745 |
747 All pushed files can be removed by calling RemovePushedFiles(). | 746 All pushed files can be removed by calling RemovePushedFiles(). |
748 """ | 747 """ |
| 748 assert os.path.exists(local_path), 'Local path not found %s' % local_path |
| 749 size = int(cmd_helper.GetCmdOutput(['du', '-sb', local_path]).split()[0]) |
| 750 self._pushed_files.append(device_path) |
| 751 self._potential_push_size += size |
| 752 |
749 if self.CheckMd5Sum(local_path, device_path): | 753 if self.CheckMd5Sum(local_path, device_path): |
750 return | 754 return |
751 | 755 |
| 756 self._actual_push_size += size |
752 # They don't match, so remove everything first and then create it. | 757 # They don't match, so remove everything first and then create it. |
753 if os.path.isdir(local_path): | 758 if os.path.isdir(local_path): |
754 self.RunShellCommand('rm -r %s' % device_path, timeout_time=2 * 60) | 759 self.RunShellCommand('rm -r %s' % device_path, timeout_time=2 * 60) |
755 self.RunShellCommand('mkdir -p %s' % device_path) | 760 self.RunShellCommand('mkdir -p %s' % device_path) |
756 | 761 |
757 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout of | 762 # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout of |
758 # 60 seconds which isn't sufficient for a lot of users of this method. | 763 # 60 seconds which isn't sufficient for a lot of users of this method. |
759 push_command = 'push %s %s' % (local_path, device_path) | 764 push_command = 'push %s %s' % (local_path, device_path) |
760 self._LogShell(push_command) | 765 self._LogShell(push_command) |
761 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) | 766 output = self._adb.SendCommand(push_command, timeout_time=30 * 60) |
762 assert _HasAdbPushSucceeded(output) | 767 assert _HasAdbPushSucceeded(output) |
763 | 768 |
| 769 def GetPushSizeInfo(self): |
| 770 """Get total size of pushes to the device done via PushIfNeeded() |
| 771 |
| 772 Returns: |
| 773 A tuple: |
| 774 1. Total size of push requests to PushIfNeeded (MB) |
| 775 2. Total size that was actually pushed (MB) |
| 776 """ |
| 777 return (self._potential_push_size, self._actual_push_size) |
764 | 778 |
765 def GetFileContents(self, filename, log_result=False): | 779 def GetFileContents(self, filename, log_result=False): |
766 """Gets contents from the file specified by |filename|.""" | 780 """Gets contents from the file specified by |filename|.""" |
767 return self.RunShellCommand('cat "%s" 2>/dev/null' % filename, | 781 return self.RunShellCommand('cat "%s" 2>/dev/null' % filename, |
768 log_result=log_result) | 782 log_result=log_result) |
769 | 783 |
770 def SetFileContents(self, filename, contents): | 784 def SetFileContents(self, filename, contents): |
771 """Writes |contents| to the file specified by |filename|.""" | 785 """Writes |contents| to the file specified by |filename|.""" |
772 with tempfile.NamedTemporaryFile() as f: | 786 with tempfile.NamedTemporaryFile() as f: |
773 f.write(contents) | 787 f.write(contents) |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 """ | 1365 """ |
1352 def __init__(self, output): | 1366 def __init__(self, output): |
1353 self._output = output | 1367 self._output = output |
1354 | 1368 |
1355 def write(self, data): | 1369 def write(self, data): |
1356 data = data.replace('\r\r\n', '\n') | 1370 data = data.replace('\r\r\n', '\n') |
1357 self._output.write(data) | 1371 self._output.write(data) |
1358 | 1372 |
1359 def flush(self): | 1373 def flush(self): |
1360 self._output.flush() | 1374 self._output.flush() |
OLD | NEW |