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 # pylint: disable-all | 9 # pylint: disable-all |
10 | 10 |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 # Md5Sum resolves symbolic links in path names so the calculation of | 944 # Md5Sum resolves symbolic links in path names so the calculation of |
945 # relative path names from its output will need the real path names of the | 945 # relative path names from its output will need the real path names of the |
946 # base directories. Having calculated these they are used throughout the | 946 # base directories. Having calculated these they are used throughout the |
947 # function since this makes us less subject to any future changes to Md5Sum. | 947 # function since this makes us less subject to any future changes to Md5Sum. |
948 real_host_path = os.path.realpath(host_path) | 948 real_host_path = os.path.realpath(host_path) |
949 real_device_path = self.RunShellCommand('realpath "%s"' % device_path)[0] | 949 real_device_path = self.RunShellCommand('realpath "%s"' % device_path)[0] |
950 | 950 |
951 host_hash_tuples, device_hash_tuples = self._RunMd5Sum( | 951 host_hash_tuples, device_hash_tuples = self._RunMd5Sum( |
952 real_host_path, real_device_path) | 952 real_host_path, real_device_path) |
953 | 953 |
954 # Ignore extra files on the device. | |
955 if not ignore_filenames: | |
956 host_files = [os.path.relpath(os.path.normpath(p.path), | |
957 real_host_path) for p in host_hash_tuples] | |
958 | |
959 def HostHas(fname): | |
960 return any(path in fname for path in host_files) | |
961 | |
962 device_hash_tuples = [h for h in device_hash_tuples if HostHas(h.path)] | |
963 | |
964 if len(host_hash_tuples) > len(device_hash_tuples): | 954 if len(host_hash_tuples) > len(device_hash_tuples): |
965 logging.info('%s files do not exist on the device' % | 955 logging.info('%s files do not exist on the device' % |
966 (len(host_hash_tuples) - len(device_hash_tuples))) | 956 (len(host_hash_tuples) - len(device_hash_tuples))) |
967 | 957 |
968 # Constructs the target device path from a given host path. Don't use when | 958 host_rel = [(os.path.relpath(os.path.normpath(t.path), real_host_path), |
969 # only a single file is given as the base name given in device_path may | 959 t.hash) |
970 # differ from that in host_path. | 960 for t in host_hash_tuples] |
971 def HostToDevicePath(host_file_path): | |
972 return os.path.join(device_path, os.path.relpath(host_file_path, | |
973 real_host_path)) | |
974 | 961 |
975 device_hashes = [h.hash for h in device_hash_tuples] | 962 if os.path.isdir(real_host_path): |
976 return [(t.path, HostToDevicePath(t.path) if | 963 def RelToRealPaths(rel_path): |
977 os.path.isdir(real_host_path) else real_device_path) | 964 return (os.path.join(real_host_path, rel_path), |
978 for t in host_hash_tuples if t.hash not in device_hashes] | 965 os.path.join(real_device_path, rel_path)) |
| 966 else: |
| 967 assert len(host_rel) == 1 |
| 968 def RelToRealPaths(_): |
| 969 return (real_host_path, real_device_path) |
| 970 |
| 971 if ignore_filenames: |
| 972 # If we are ignoring file names, then we want to push any file for which |
| 973 # a file with an equivalent MD5 sum does not exist on the device. |
| 974 device_hashes = set([h.hash for h in device_hash_tuples]) |
| 975 ShouldPush = lambda p, h: h not in device_hashes |
| 976 else: |
| 977 # Otherwise, we want to push any file on the host for which a file with |
| 978 # an equivalent MD5 sum does not exist at the same relative path on the |
| 979 # device. |
| 980 device_rel = dict([(os.path.relpath(os.path.normpath(t.path), |
| 981 real_device_path), |
| 982 t.hash) |
| 983 for t in device_hash_tuples]) |
| 984 ShouldPush = lambda p, h: p not in device_rel or h != device_rel[p] |
| 985 |
| 986 return [RelToRealPaths(path) for path, host_hash in host_rel |
| 987 if ShouldPush(path, host_hash)] |
979 | 988 |
980 def PushIfNeeded(self, host_path, device_path): | 989 def PushIfNeeded(self, host_path, device_path): |
981 """Pushes |host_path| to |device_path|. | 990 """Pushes |host_path| to |device_path|. |
982 | 991 |
983 Works for files and directories. This method skips copying any paths in | 992 Works for files and directories. This method skips copying any paths in |
984 |test_data_paths| that already exist on the device with the same hash. | 993 |test_data_paths| that already exist on the device with the same hash. |
985 | 994 |
986 All pushed files can be removed by calling RemovePushedFiles(). | 995 All pushed files can be removed by calling RemovePushedFiles(). |
987 """ | 996 """ |
988 MAX_INDIVIDUAL_PUSHES = 50 | 997 MAX_INDIVIDUAL_PUSHES = 50 |
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 """ | 1846 """ |
1838 def __init__(self, output): | 1847 def __init__(self, output): |
1839 self._output = output | 1848 self._output = output |
1840 | 1849 |
1841 def write(self, data): | 1850 def write(self, data): |
1842 data = data.replace('\r\r\n', '\n') | 1851 data = data.replace('\r\r\n', '\n') |
1843 self._output.write(data) | 1852 self._output.write(data) |
1844 | 1853 |
1845 def flush(self): | 1854 def flush(self): |
1846 self._output.flush() | 1855 self._output.flush() |
OLD | NEW |