Index: build/android/pylib/device/device_utils.py |
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py |
index 46aec6fc9df0eb7b94b89628457567a692299b81..091bb8ed07e514c24718999a35dfb6440bc408d4 100644 |
--- a/build/android/pylib/device/device_utils.py |
+++ b/build/android/pylib/device/device_utils.py |
@@ -175,6 +175,29 @@ class DeviceUtils(object): |
assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) |
assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR) |
+ def __eq__(self, other): |
+ """Checks whether |other| refers to the same device as |self|. |
+ |
+ Args: |
+ other: The object to compare to. This can be a basestring, an instance |
+ of adb_wrapper.AdbWrapper, or an instance of DeviceUtils. |
+ Returns: |
+ Whether |other| refers to the same device as |self|. |
+ """ |
+ return self.adb.GetDeviceSerial() == str(other) |
+ |
+ def __lt__(self, other): |
+ """Compares two instances of DeviceUtils. |
+ |
+ This merely compares their serial numbers. |
+ |
+ Args: |
+ other: The instance of DeviceUtils to compare to. |
+ Returns: |
+ Whether |self| is less than |other|. |
+ """ |
+ return self.adb.GetDeviceSerial() < other.adb.GetDeviceSerial() |
+ |
def __str__(self): |
"""Returns the device serial.""" |
return self.adb.GetDeviceSerial() |
@@ -535,9 +558,9 @@ class DeviceUtils(object): |
with device_temp_file.DeviceTempFile(self.adb) as large_output_file: |
cmd = '%s > %s' % (cmd, large_output_file.name) |
logging.info('Large output mode enabled. Will write output to device ' |
- ' and read results from file.') |
+ 'and read results from file.') |
handle_large_command(cmd) |
- return self.ReadFile(large_output_file.name) |
+ return self.ReadFile(large_output_file.name, force_pull=True) |
else: |
try: |
return handle_large_command(cmd) |
@@ -853,13 +876,17 @@ class DeviceUtils(object): |
if not real_device_path: |
return [(host_path, device_path)] |
- host_checksums = md5sum.CalculateHostMd5Sums([real_host_path]) |
- device_paths_to_md5 = ( |
- real_device_path if os.path.isfile(real_host_path) |
- else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path)) |
- for p in host_checksums.iterkeys())) |
- device_checksums = md5sum.CalculateDeviceMd5Sums( |
- device_paths_to_md5, self) |
+ try: |
+ host_checksums = md5sum.CalculateHostMd5Sums([real_host_path]) |
+ device_paths_to_md5 = ( |
+ real_device_path if os.path.isfile(real_host_path) |
+ else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path)) |
+ for p in host_checksums.iterkeys())) |
+ device_checksums = md5sum.CalculateDeviceMd5Sums( |
+ device_paths_to_md5, self) |
+ except EnvironmentError as e: |
+ logging.warning('Error calculating md5: %s', e) |
+ return [(host_path, device_path)] |
if os.path.isfile(host_path): |
host_checksum = host_checksums.get(real_host_path) |
@@ -1016,7 +1043,7 @@ class DeviceUtils(object): |
+ r'(?P<date>\S+) +(?P<time>\S+) +(?P<name>.+)$') |
@decorators.WithTimeoutAndRetriesFromInstance() |
- def ReadFile(self, device_path, as_root=False, |
+ def ReadFile(self, device_path, as_root=False, force_pull=False, |
timeout=None, retries=None): |
"""Reads the contents of a file from the device. |
@@ -1025,6 +1052,9 @@ class DeviceUtils(object): |
from the device. |
as_root: A boolean indicating whether the read should be executed with |
root privileges. |
+ force_pull: A boolean indicating whether to force the operation to be |
+ performed by pulling a file from the device. The default is, when the |
+ contents are short, to retrieve the contents using cat instead. |
timeout: timeout in seconds |
retries: number of retries |
@@ -1038,20 +1068,20 @@ class DeviceUtils(object): |
CommandTimeoutError on timeout. |
DeviceUnreachableError on missing device. |
""" |
- # TODO(jbudorick): Implement a generic version of Stat() that handles |
- # as_root=True, then switch this implementation to use that. |
- size = None |
- ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root, |
- check_return=True) |
- for line in ls_out: |
- m = self._LS_RE.match(line) |
- if m and m.group('name') == posixpath.basename(device_path): |
- size = int(m.group('size')) |
- break |
- else: |
+ def get_size(path): |
+ # TODO(jbudorick): Implement a generic version of Stat() that handles |
+ # as_root=True, then switch this implementation to use that. |
+ ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root, |
+ check_return=True) |
+ for line in ls_out: |
+ m = self._LS_RE.match(line) |
+ if m and m.group('name') == posixpath.basename(device_path): |
+ return int(m.group('size')) |
logging.warning('Could not determine size of %s.', device_path) |
+ return None |
- if 0 < size <= self._MAX_ADB_OUTPUT_LENGTH: |
+ if (not force_pull |
+ and 0 < get_size(device_path) <= self._MAX_ADB_OUTPUT_LENGTH): |
return _JoinLines(self.RunShellCommand( |
['cat', device_path], as_root=as_root, check_return=True)) |
elif as_root and self.NeedsSU(): |