Chromium Code Reviews| Index: build/android/devil/android/device_utils.py |
| diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py |
| index 432677f91917734e31f48c9392339ce3c30de90d..1d315cd2757d26dccffb7bae5fe2e4b6cac9cca9 100644 |
| --- a/build/android/devil/android/device_utils.py |
| +++ b/build/android/devil/android/device_utils.py |
| @@ -10,6 +10,7 @@ Eventually, this will be based on adb_wrapper. |
| import collections |
| import itertools |
| +import json |
| import logging |
| import multiprocessing |
| import os |
| @@ -163,7 +164,8 @@ class DeviceUtils(object): |
| # Property in /data/local.prop that controls Java assertions. |
| JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' |
| - def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, |
| + def __init__(self, device, enable_device_files_cache=False, |
|
jbudorick
2015/10/01 17:15:26
Document this parameter.
agrieve
2015/10/01 18:30:16
Done.
|
| + default_timeout=_DEFAULT_TIMEOUT, |
| default_retries=_DEFAULT_RETRIES): |
| """DeviceUtils constructor. |
| @@ -187,6 +189,7 @@ class DeviceUtils(object): |
| self._commands_installed = None |
| self._default_timeout = default_timeout |
| self._default_retries = default_retries |
| + self._enable_device_files_cache = enable_device_files_cache |
| self._cache = {} |
| self._client_caches = {} |
| assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) |
| @@ -1102,14 +1105,31 @@ class DeviceUtils(object): |
| track_stale == False |
| """ |
| try: |
| - host_checksums = md5sum.CalculateHostMd5Sums([host_path]) |
| - interesting_device_paths = [device_path] |
| - if not track_stale and os.path.isdir(host_path): |
| - interesting_device_paths = [ |
| - posixpath.join(device_path, os.path.relpath(p, host_path)) |
| - for p in host_checksums.keys()] |
| - device_checksums = md5sum.CalculateDeviceMd5Sums( |
| - interesting_device_paths, self) |
| + specific_device_paths = [device_path] |
| + ignore_other_files = not track_stale and os.path.isdir(host_path) |
| + if ignore_other_files: |
| + specific_device_paths = [] |
| + for root, _, filenames in os.walk(host_path): |
| + relative_dir = root[len(host_path) + 1:] |
| + specific_device_paths.extend( |
| + posixpath.join(device_path, relative_dir, f) for f in filenames) |
| + |
| + def device_sums_helper(): |
| + if self._enable_device_files_cache: |
| + cache_entry = self._cache['device_path_checksums'].get(device_path) |
| + if cache_entry and cache_entry[0] == ignore_other_files: |
| + return dict(cache_entry[1]) |
| + |
| + sums = md5sum.CalculateDeviceMd5Sums(specific_device_paths, self) |
| + |
| + if self._enable_device_files_cache: |
| + cache_entry = [ignore_other_files, sums] |
| + self._cache['device_path_checksums'][device_path] = cache_entry |
| + return dict(sums) |
| + |
| + host_checksums, device_checksums = reraiser_thread.RunAsync(( |
| + lambda: md5sum.CalculateHostMd5Sums([host_path]), |
| + device_sums_helper)) |
| except EnvironmentError as e: |
| logging.warning('Error calculating md5: %s', e) |
| return ([(host_path, device_path)], [], []) |
| @@ -1917,8 +1937,32 @@ class DeviceUtils(object): |
| 'package_apk_checksums': {}, |
| # Map of property_name -> value |
| 'getprop': {}, |
| + # Map of device_path -> [ignore_other_files, map of path->checksum] |
|
jbudorick
2015/10/01 17:15:26
Isn't this just a map of device_path -> checksum?
agrieve
2015/10/01 18:30:16
The comment is correct. The reason it's not a map
|
| + 'device_path_checksums': {}, |
| } |
| + def LoadCacheData(self, data): |
| + """Initializes the cache from data created using DumpCacheData.""" |
| + obj = json.loads(data) |
| + self._cache['package_apk_paths'] = obj.get('package_apk_paths', {}) |
| + package_apk_checksums = obj.get('package_apk_checksums', {}) |
| + for k, v in package_apk_checksums.iteritems(): |
| + package_apk_checksums[k] = set(v) |
| + self._cache['package_apk_checksums'] = package_apk_checksums |
| + device_path_checksums = obj.get('device_path_checksums', {}) |
| + self._cache['device_path_checksums'] = device_path_checksums |
| + |
| + def DumpCacheData(self): |
| + """Dumps the current cache state to a string.""" |
| + obj = {} |
| + obj['package_apk_paths'] = self._cache['package_apk_paths'] |
| + obj['package_apk_checksums'] = self._cache['package_apk_checksums'] |
| + # JSON can't handle sets. |
| + for k, v in obj['package_apk_checksums'].iteritems(): |
| + obj['package_apk_checksums'][k] = list(v) |
| + obj['device_path_checksums'] = self._cache['device_path_checksums'] |
| + return json.dumps(obj, separators=(',', ':')) |
| + |
| @classmethod |
| def parallel(cls, devices, async=False): |
| """Creates a Parallelizer to operate over the provided list of devices. |