Chromium Code Reviews| Index: build/android/incremental_install/installer.py |
| diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py |
| index 15bdbeeb2ef9d06e0409ea1b6d559508221c4b72..b5b1d050e5510261198775f8e5fe52a2a743bff4 100755 |
| --- a/build/android/incremental_install/installer.py |
| +++ b/build/android/incremental_install/installer.py |
| @@ -13,6 +13,7 @@ import os |
| import posixpath |
| import shutil |
| import sys |
| +import zipfile |
| sys.path.append( |
| os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))) |
| @@ -32,6 +33,11 @@ from util import build_utils |
| sys.path = prev_sys_path |
| +def _DeviceCachePath(device): |
| + file_name = 'device_cache_%s.json' % device.adb.GetDeviceSerial() |
| + return os.path.join(constants.GetOutDirectory(), file_name) |
|
nyquist
2016/02/10 07:08:32
Does constants.GetOutDirectory magically change de
agrieve
2016/02/10 16:47:15
It is somewhat comically named. There's a setter f
jbudorick
2016/02/10 16:53:14
constants.GetOutDirectory() is one of my pet peeve
|
| + |
| + |
| def _TransformDexPaths(paths): |
| """Given paths like ["/a/b/c", "/a/c/d"], returns ["b.c", "c.d"].""" |
| if len(paths) == 1: |
| @@ -58,17 +64,28 @@ def _GetDeviceIncrementalDir(package): |
| return '/data/local/tmp/incremental-app-%s' % package |
| -def Uninstall(device, package): |
| +def _HasClasses(jar_path): |
| + """Returns whether the given jar contains classes.dex.""" |
| + with zipfile.ZipFile(jar_path) as jar: |
| + return 'classes.dex' in jar.namelist() |
| + |
| + |
| +def Uninstall(device, package, enable_device_cache=False): |
| """Uninstalls and removes all incremental files for the given package.""" |
| main_timer = time_profile.TimeProfile() |
| device.Uninstall(package) |
| + if enable_device_cache: |
| + # Uninstall is rare, so just wipe the cache in this case. |
| + cache_path = _DeviceCachePath(device) |
| + if os.path.exists(cache_path): |
| + os.unlink(cache_path) |
| device.RunShellCommand(['rm', '-rf', _GetDeviceIncrementalDir(package)], |
| check_return=True) |
| logging.info('Uninstall took %s seconds.', main_timer.GetDelta()) |
| def Install(device, apk, split_globs=None, native_libs=None, dex_files=None, |
| - enable_device_cache=True, use_concurrency=True, |
| + enable_device_cache=False, use_concurrency=True, |
| show_proguard_warning=False): |
| """Installs the given incremental apk and all required supporting files. |
| @@ -128,7 +145,10 @@ def Install(device, apk, split_globs=None, native_libs=None, dex_files=None, |
| # Ensure no two files have the same name. |
| transformed_names = _TransformDexPaths(dex_files) |
| for src_path, dest_name in zip(dex_files, transformed_names): |
| - shutil.copy(src_path, os.path.join(temp_dir, dest_name)) |
| + # Binary targets with no extra classes create .dex.jar without a |
| + # classes.dex (which Android chokes on). |
| + if _HasClasses(src_path): |
| + shutil.copy(src_path, os.path.join(temp_dir, dest_name)) |
| device.PushChangedFiles([(temp_dir, device_dex_dir)], |
| delete_device_stale=True) |
| push_dex_timer.Stop(log=False) |
| @@ -144,23 +164,24 @@ def Install(device, apk, split_globs=None, native_libs=None, dex_files=None, |
| 'To do so, use GN arg:\n' |
| ' disable_incremental_isolated_processes=true') |
| - cache_path = '%s/files-cache.json' % device_incremental_dir |
| + cache_path = _DeviceCachePath(device) |
| def restore_cache(): |
| if not enable_device_cache: |
| logging.info('Ignoring device cache') |
| return |
| - # Delete the cached file so that any exceptions cause the next attempt |
| - # to re-compute md5s. |
| - cmd = 'P=%s;cat $P 2>/dev/null && rm $P' % cache_path |
| - lines = device.RunShellCommand(cmd, check_return=False, large_output=True) |
| - if lines: |
| - device.LoadCacheData(lines[0]) |
| + if os.path.exists(cache_path): |
| + logging.info('Using device cache: %s', cache_path) |
| + with open(cache_path) as f: |
| + device.LoadCacheData(f.read()) |
| + # Delete the cached file so that any exceptions cause it to be cleared. |
| + os.unlink(cache_path) |
| else: |
| - logging.info('Device cache not found: %s', cache_path) |
| + logging.info('No device cache present: %s', cache_path) |
| def save_cache(): |
| - cache_data = device.DumpCacheData() |
| - device.WriteFile(cache_path, cache_data) |
| + with open(cache_path, 'w') as f: |
| + f.write(device.DumpCacheData()) |
| + logging.info('Wrote device cache: %s', cache_path) |
| # Create 2 lock files: |
| # * install.lock tells the app to pause on start-up (until we release it). |
| @@ -281,7 +302,7 @@ def main(): |
| apk = apk_helper.ToHelper(args.apk_path) |
| if args.uninstall: |
| - Uninstall(device, apk.GetPackageName()) |
| + Uninstall(device, apk.GetPackageName(), enable_device_cache=args.cache) |
| else: |
| Install(device, apk, split_globs=args.splits, native_libs=args.native_libs, |
| dex_files=args.dex_files, enable_device_cache=args.cache, |