Index: build/android/pylib/android_commands.py |
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py |
index 4cf070d0711a9626edf1ba6eae35efe0f7bb7e40..8687d5401c1d11279ae6de50f5d934b7e71804b9 100644 |
--- a/build/android/pylib/android_commands.py |
+++ b/build/android/pylib/android_commands.py |
@@ -738,15 +738,15 @@ class AndroidCommands(object): |
""" |
self.RunShellCommand('input keyevent %d' % keycode) |
- def CheckMd5Sum(self, local_path, device_path): |
- """Compares the md5sum of a local path against a device path. |
+ def _RunMd5Sum(self, local_path, device_path): |
+ """Gets the md5sum of a local path and device path. |
Args: |
local_path: Path (file or directory) on the host. |
device_path: Path on the device. |
Returns: |
- True if the md5sums match. |
+ A tuple containing lists of the local and device md5sum results. |
frankf
2013/07/31 22:58:19
Define exactly what tuple is.
craigdh
2013/08/05 23:55:43
Done.
|
""" |
if not self._md5sum_build_dir: |
default_build_type = os.environ.get('BUILD_TYPE', 'Debug') |
@@ -769,6 +769,22 @@ class AndroidCommands(object): |
md5sum_output = cmd_helper.GetCmdOutput( |
['%s/md5sum_bin_host' % self._md5sum_build_dir, local_path]) |
host_hash_tuples = _ComputeFileListHash(md5sum_output.splitlines()) |
+ return (host_hash_tuples, device_hash_tuples) |
+ |
+ def GetFileDiff(self, local_path, device_path): |
frankf
2013/07/31 22:58:19
GetFileDiff -> GetFilesChanged
craigdh
2013/08/05 23:55:43
Done.
|
+ """Compares the md5sum of a local path against a device path. |
+ |
+ Note: Ignores extra files on the device. |
+ |
+ Args: |
+ local_path: Path (file or directory) on the host. |
+ device_path: Path on the device. |
+ |
+ Returns: |
+ A list of files whose md5sums do not match. |
+ """ |
+ host_hash_tuples, device_hash_tuples = self._RunMd5Sum( |
+ local_path, device_path) |
# Ignore extra files on the device. |
if len(device_hash_tuples) > len(host_hash_tuples): |
@@ -778,16 +794,30 @@ class AndroidCommands(object): |
def _host_has(fname): |
frankf
2013/07/31 22:58:19
naming issue
craigdh
2013/08/05 23:55:43
Done.
|
return any(path in fname for path in host_files) |
- hashes_on_device = [h.hash for h in device_hash_tuples if |
- _host_has(h.path)] |
- else: |
- hashes_on_device = [h.hash for h in device_hash_tuples] |
+ device_hash_tuples = [h for h in device_hash_tuples if _host_has(h.path)] |
+ |
+ # Constructs the target device path from a given host path. Don't use when |
+ # only a single file is given as the device_path may specify a rename. |
frankf
2013/07/31 22:58:19
What rename?
craigdh
2013/08/05 23:55:43
If the local_path and device_path refer to a file
|
+ def _h2d_path(host_path): |
frankf
2013/07/31 22:58:19
Use our naming convention
craigdh
2013/08/05 23:55:43
Done.
|
+ return os.path.join(os.path.dirname(device_path), os.path.relpath( |
+ host_path, os.path.dirname(os.path.normpath(local_path)))) |
+ |
+ device_hashes = [h.hash for h in device_hash_tuples] |
+ return [(t.path, |
+ _h2d_path(t.path) if os.path.isdir(local_path) else device_path) |
frankf
2013/07/31 22:58:19
You're returning a list of tuples, this doesn't ma
craigdh
2013/08/05 23:55:43
Done.
|
+ for t in host_hash_tuples if t.hash not in device_hashes] |
+ |
+ def CheckMd5Sum(self, local_path, device_path): |
+ """Compares the md5sum of a local path against a device path. |
- # Compare md5sums between host and device files. |
- hashes_on_host = [h.hash for h in host_hash_tuples] |
- hashes_on_device.sort() |
- hashes_on_host.sort() |
- return hashes_on_device == hashes_on_host |
+ Args: |
+ local_path: Path (file or directory) on the host. |
+ device_path: Path on the device. |
+ |
+ Returns: |
+ True if the md5sums match. |
+ """ |
+ return not self.GetFileDiff(local_path, device_path) |
def PushIfNeeded(self, local_path, device_path): |
"""Pushes |local_path| to |device_path|. |
frankf
2013/07/31 22:58:19
rename local to host everywhere
craigdh
2013/08/05 23:55:43
Done.
|
@@ -798,38 +828,51 @@ class AndroidCommands(object): |
All pushed files can be removed by calling RemovePushedFiles(). |
""" |
assert os.path.exists(local_path), 'Local path not found %s' % local_path |
- size = int(cmd_helper.GetCmdOutput(['du', '-sb', local_path]).split()[0]) |
+ |
+ def _get_local_size(path): |
+ return int(cmd_helper.GetCmdOutput(['du', '-sb', path]).split()[0]) |
+ |
+ size = _get_local_size(local_path) |
self._pushed_files.append(device_path) |
self._potential_push_size += size |
- if self.CheckMd5Sum(local_path, device_path): |
+ missing_files = self.GetFileDiff(local_path, device_path) |
+ if not missing_files: |
return |
- self._actual_push_size += size |
- # They don't match, so remove everything first and then create it. |
- if os.path.isdir(local_path): |
- self.RunShellCommand('rm -r %s' % device_path, timeout_time=2 * 60) |
- self.RunShellCommand('mkdir -p %s' % device_path) |
- |
- # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout of |
- # 60 seconds which isn't sufficient for a lot of users of this method. |
- push_command = 'push %s %s' % (local_path, device_path) |
- self._LogShell(push_command) |
- |
- # Retry push with increasing backoff if the device is busy. |
- retry = 0 |
- while True: |
- output = self._adb.SendCommand(push_command, timeout_time=30 * 60) |
- if _HasAdbPushSucceeded(output): |
- return |
- if 'resource busy' in output and retry < 3: |
- retry += 1 |
- wait_time = 5 * retry |
- logging.error('Push failed, retrying in %d seconds: %s' % |
- (wait_time, output)) |
- time.sleep(wait_time) |
- else: |
- raise Exception('Push failed: %s' % output) |
+ def _push(local, device): |
frankf
2013/07/31 22:58:19
Naming
craigdh
2013/08/05 23:55:43
Done.
|
+ # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout |
+ # of 60 seconds which isn't sufficient for a lot of users of this method. |
+ push_command = 'push %s %s' % (local, device) |
+ self._LogShell(push_command) |
+ |
+ # Retry push with increasing backoff if the device is busy. |
+ retry = 0 |
+ while True: |
+ output = self._adb.SendCommand(push_command, timeout_time=30 * 60) |
+ if _HasAdbPushSucceeded(output): |
+ return |
+ if 'resource busy' in output and retry < 3: |
+ retry += 1 |
+ wait_time = 5 * retry |
+ logging.error('Push failed, retrying in %d seconds: %s' % |
+ (wait_time, output)) |
+ time.sleep(wait_time) |
+ else: |
+ raise Exception('Push failed: %s' % output) |
+ |
+ # Above a small number of files it's likely faster to push everything. |
+ if len(missing_files) > 20: |
frankf
2013/07/31 22:58:19
This is very arbitrary. Why number of files instea
craigdh
2013/08/05 23:55:43
Based on size for now with a cutoff and added a TO
|
+ # We're pushing everything, remove everything first and then create it. |
+ self._actual_push_size += size |
+ if os.path.isdir(local_path): |
+ self.RunShellCommand('rm -r %s' % device_path, timeout_time=2 * 60) |
+ self.RunShellCommand('mkdir -p %s' % device_path) |
+ _push(local_path, device_path) |
+ else: |
+ for f in missing_files: |
+ self._actual_push_size += _get_local_size(f[0]) |
+ _push(f[0], f[1]) |
def GetPushSizeInfo(self): |
"""Get total size of pushes to the device done via PushIfNeeded() |