Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
| 6 | 6 |
| 7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
| 8 """ | 8 """ |
| 9 # pylint: disable=unused-argument | 9 # pylint: disable=unused-argument |
| 10 | 10 |
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 | 829 |
| 830 files = [] | 830 files = [] |
| 831 for h, d in host_device_tuples: | 831 for h, d in host_device_tuples: |
| 832 if os.path.isdir(h): | 832 if os.path.isdir(h): |
| 833 self.RunShellCommand(['mkdir', '-p', d], check_return=True) | 833 self.RunShellCommand(['mkdir', '-p', d], check_return=True) |
| 834 files += self._GetChangedFilesImpl(h, d) | 834 files += self._GetChangedFilesImpl(h, d) |
| 835 | 835 |
| 836 if not files: | 836 if not files: |
| 837 return | 837 return |
| 838 | 838 |
| 839 self._PushFilesImpl(host_device_tuples, files) | |
| 840 | |
| 841 def _GetChangedFilesImpl(self, host_path, device_path): | |
| 842 (real_host_path, real_device_path) = self._GetRealHostDevicePaths( | |
| 843 host_path, device_path) | |
| 844 if not real_device_path: | |
| 845 return [(host_path, device_path)] | |
| 846 | |
| 847 try: | |
| 848 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path]) | |
| 849 device_paths_to_md5 = ( | |
| 850 real_device_path if os.path.isfile(real_host_path) | |
| 851 else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path)) | |
| 852 for p in host_checksums.iterkeys())) | |
| 853 device_checksums = md5sum.CalculateDeviceMd5Sums( | |
| 854 device_paths_to_md5, self) | |
| 855 except EnvironmentError as e: | |
| 856 logging.warning('Error calculating md5: %s', e) | |
| 857 return [(host_path, device_path)] | |
| 858 | |
| 859 if os.path.isfile(host_path): | |
| 860 host_checksum = host_checksums.get(real_host_path) | |
| 861 device_checksum = device_checksums.get(real_device_path) | |
| 862 if host_checksum != device_checksum: | |
| 863 return [(host_path, device_path)] | |
| 864 else: | |
| 865 return [] | |
| 866 else: | |
| 867 to_push = [] | |
| 868 for host_abs_path, host_checksum in host_checksums.iteritems(): | |
| 869 device_abs_path = '%s/%s' % ( | |
| 870 real_device_path, os.path.relpath(host_abs_path, real_host_path)) | |
| 871 if (device_checksums.get(device_abs_path) != host_checksum): | |
| 872 to_push.append((host_abs_path, device_abs_path)) | |
| 873 return to_push | |
| 874 | |
| 875 def _GetRealHostDevicePaths(self, host_path, device_path): | |
| 876 real_host_path = os.path.realpath(host_path) | |
| 877 try: | |
| 878 real_device_path = self.RunShellCommand( | |
| 879 ['realpath', device_path], single_line=True, check_return=True) | |
| 880 except device_errors.CommandFailedError: | |
| 881 real_device_path = None | |
| 882 return (real_host_path, real_device_path) | |
| 883 | |
| 884 def _PushFilesImpl(self, host_device_tuples, files): | |
| 839 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) | 885 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) |
| 840 file_count = len(files) | 886 file_count = len(files) |
| 841 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) | 887 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) |
| 842 for h, _ in host_device_tuples) | 888 for h, _ in host_device_tuples) |
| 843 dir_file_count = 0 | 889 dir_file_count = 0 |
| 844 for h, _ in host_device_tuples: | 890 for h, _ in host_device_tuples: |
| 845 if os.path.isdir(h): | 891 if os.path.isdir(h): |
| 846 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) | 892 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) |
| 847 else: | 893 else: |
| 848 dir_file_count += 1 | 894 dir_file_count += 1 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 859 dir_push_duration < zip_duration or not self._commands_installed): | 905 dir_push_duration < zip_duration or not self._commands_installed): |
| 860 self._PushChangedFilesIndividually(host_device_tuples) | 906 self._PushChangedFilesIndividually(host_device_tuples) |
| 861 elif push_duration < zip_duration or not self._commands_installed: | 907 elif push_duration < zip_duration or not self._commands_installed: |
| 862 self._PushChangedFilesIndividually(files) | 908 self._PushChangedFilesIndividually(files) |
| 863 else: | 909 else: |
| 864 self._PushChangedFilesZipped(files) | 910 self._PushChangedFilesZipped(files) |
| 865 self.RunShellCommand( | 911 self.RunShellCommand( |
| 866 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], | 912 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], |
| 867 as_root=True, check_return=True) | 913 as_root=True, check_return=True) |
| 868 | 914 |
| 869 def _GetChangedFilesImpl(self, host_path, device_path): | 915 PUSH_AND_DELETE_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT |
| 870 real_host_path = os.path.realpath(host_path) | 916 PUSH_AND_DELETE_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES |
| 871 try: | 917 |
| 872 real_device_path = self.RunShellCommand( | 918 @decorators.WithTimeoutAndRetriesDefaults( |
| 873 ['realpath', device_path], single_line=True, check_return=True) | 919 PUSH_AND_DELETE_FILES_DEFAULT_TIMEOUT, |
| 874 except device_errors.CommandFailedError: | 920 PUSH_AND_DELETE_FILES_DEFAULT_RETRIES) |
| 875 real_device_path = None | 921 def PushAndDeleteFiles(self, device_dir, host_device_tuples, timeout=None, |
| 922 retries=None): | |
| 923 """Push changed files to the device, delete stale files, | |
| 924 skipping files that don't need updating. | |
| 925 | |
| 926 Args: | |
| 927 device_dir: the absolute path of the directory on the device which | |
| 928 has all the data dependencies | |
| 929 host_device_tuples: A list of (host_path, device_path) tuples, where | |
| 930 |host_path| is an absolute path of a file or directory on the host | |
| 931 that should be minimially pushed to the device, and |device_path| is | |
| 932 an absolute path of the destination on the device. | |
| 933 timeout: timeout in seconds | |
| 934 retries: number of retries | |
| 935 | |
| 936 Raises: | |
| 937 CommandFailedError on failure. | |
| 938 CommandTimeoutError on timeout. | |
| 939 DeviceUnreachableError on missing device. | |
| 940 """ | |
| 941 | |
| 942 real_device_dir_path = self.RunShellCommand( | |
| 943 ['realpath', device_dir], single_line=True, check_return=True) | |
| 944 device_checksums = md5sum.CalculateDeviceMd5Sums( | |
| 945 [real_device_dir_path], self) | |
| 946 | |
| 947 files = [] | |
| 948 for h, d in host_device_tuples: | |
| 949 if os.path.isdir(h): | |
| 950 self.RunShellCommand(['mkdir', '-p', d], check_return=True) | |
| 951 files += self._GetChangedFilesRemoveStaleFiles(h, d, device_checksums) | |
| 952 | |
| 953 if files: | |
| 954 self._PushFilesImpl(host_device_tuples, files) | |
| 955 self._DeleteStaleFiles(device_checksums.keys()) | |
| 956 | |
| 957 def _GetChangedFilesRemoveStaleFiles(self, host_path, device_path, | |
|
jbudorick
2015/06/02 15:30:50
This function has some significant issues:
- it d
Menglin
2015/06/02 16:31:44
device_checksums is calculated in each _GetChanged
jbudorick
2015/06/08 18:34:29
I'm not sure about that particular implementation,
perezju
2015/06/09 13:07:26
I had a good thought about this.
First, I'm not s
Menglin
2015/06/09 22:11:44
Done.
Menglin
2015/06/09 22:11:44
Done.
Menglin
2015/06/09 22:11:45
Done.
Menglin
2015/06/09 22:11:45
Acknowledged.
| |
| 958 device_checksums): | |
| 959 (real_host_path, real_device_path) = self._GetRealHostDevicePaths( | |
| 960 host_path, device_path) | |
| 876 if not real_device_path: | 961 if not real_device_path: |
| 877 return [(host_path, device_path)] | 962 return [(host_path, device_path)] |
| 878 | 963 |
| 879 try: | 964 try: |
| 880 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path]) | 965 host_checksums = md5sum.CalculateHostMd5Sums([real_host_path]) |
| 881 device_paths_to_md5 = ( | |
| 882 real_device_path if os.path.isfile(real_host_path) | |
| 883 else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path)) | |
| 884 for p in host_checksums.iterkeys())) | |
| 885 device_checksums = md5sum.CalculateDeviceMd5Sums( | |
| 886 device_paths_to_md5, self) | |
| 887 except EnvironmentError as e: | 966 except EnvironmentError as e: |
| 888 logging.warning('Error calculating md5: %s', e) | 967 logging.warning('Error calculating md5: %s', e) |
| 889 return [(host_path, device_path)] | 968 return [(host_path, device_path)] |
| 890 | 969 |
| 891 if os.path.isfile(host_path): | 970 if os.path.isfile(host_path): |
| 892 host_checksum = host_checksums.get(real_host_path) | 971 host_checksum = host_checksums.get(real_host_path) |
| 893 device_checksum = device_checksums.get(real_device_path) | 972 device_checksum = device_checksums.get(real_device_path) |
| 973 if real_device_path in device_checksums: | |
| 974 del device_checksums[real_device_path] | |
| 894 if host_checksum != device_checksum: | 975 if host_checksum != device_checksum: |
| 895 return [(host_path, device_path)] | 976 return [(host_path, device_path)] |
| 896 else: | 977 else: |
| 897 return [] | 978 return [] |
| 898 else: | 979 else: |
| 899 to_push = [] | 980 to_push = [] |
| 900 for host_abs_path, host_checksum in host_checksums.iteritems(): | 981 for host_abs_path, host_checksum in host_checksums.iteritems(): |
| 901 device_abs_path = '%s/%s' % ( | 982 device_abs_path = '%s/%s' % ( |
| 902 real_device_path, os.path.relpath(host_abs_path, real_host_path)) | 983 real_device_path, os.path.relpath(host_abs_path, real_host_path)) |
| 903 if (device_checksums.get(device_abs_path) != host_checksum): | 984 device_checksum = device_checksums.get(device_abs_path) |
| 985 if device_abs_path in device_checksums: | |
| 986 del device_checksums[device_abs_path] | |
| 987 if (device_checksum != host_checksum): | |
| 904 to_push.append((host_abs_path, device_abs_path)) | 988 to_push.append((host_abs_path, device_abs_path)) |
| 905 return to_push | 989 return to_push |
| 906 | 990 |
| 991 def _DeleteStaleFiles(self, stale_files): | |
| 992 for stale_file_path in stale_files: | |
| 993 self.RunShellCommand(['rm', stale_file_path]) | |
| 994 | |
| 907 def _InstallCommands(self): | 995 def _InstallCommands(self): |
| 908 if self._commands_installed is None: | 996 if self._commands_installed is None: |
| 909 try: | 997 try: |
| 910 if not install_commands.Installed(self): | 998 if not install_commands.Installed(self): |
| 911 install_commands.InstallCommands(self) | 999 install_commands.InstallCommands(self) |
| 912 self._commands_installed = True | 1000 self._commands_installed = True |
| 913 except Exception as e: | 1001 except Exception as e: |
| 914 logging.warning('unzip not available: %s' % str(e)) | 1002 logging.warning('unzip not available: %s' % str(e)) |
| 915 self._commands_installed = False | 1003 self._commands_installed = False |
| 916 | 1004 |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 blacklist = device_blacklist.ReadBlacklist() | 1699 blacklist = device_blacklist.ReadBlacklist() |
| 1612 def blacklisted(adb): | 1700 def blacklisted(adb): |
| 1613 if adb.GetDeviceSerial() in blacklist: | 1701 if adb.GetDeviceSerial() in blacklist: |
| 1614 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial()) | 1702 logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial()) |
| 1615 return True | 1703 return True |
| 1616 return False | 1704 return False |
| 1617 | 1705 |
| 1618 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices() | 1706 return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices() |
| 1619 if not blacklisted(adb)] | 1707 if not blacklisted(adb)] |
| 1620 | 1708 |
| OLD | NEW |