| Index: build/android/incremental_install/installer.py
|
| diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py
|
| index bc0954b524aababe8dba37bd48b9691840d84cb0..1a58941edd6dece554834ad1fb65bb0248eca9fb 100755
|
| --- a/build/android/incremental_install/installer.py
|
| +++ b/build/android/incremental_install/installer.py
|
| @@ -34,6 +34,18 @@ def _TransformDexPaths(paths):
|
| return [p[prefix_len:].replace(os.sep, '.') for p in paths]
|
|
|
|
|
| +def _Execute(concurrently, *funcs):
|
| + """Calls all functions in |funcs| concurrently or in sequence."""
|
| + timer = time_profile.TimeProfile()
|
| + if concurrently:
|
| + reraiser_thread.RunAsync(funcs)
|
| + else:
|
| + for f in funcs:
|
| + f()
|
| + timer.Stop(log=False)
|
| + return timer
|
| +
|
| +
|
| def main():
|
| parser = argparse.ArgumentParser()
|
| parser.add_argument('apk_path',
|
| @@ -58,8 +70,9 @@ def main():
|
| parser.add_argument('--output-directory',
|
| help='Path to the root build directory.')
|
| parser.add_argument('--no-threading',
|
| - action='store_true',
|
| - default=False,
|
| + action='store_false',
|
| + default=True,
|
| + dest='threading',
|
| help='Do not install and push concurrently')
|
| parser.add_argument('-v',
|
| '--verbose',
|
| @@ -83,9 +96,11 @@ def main():
|
| if args.device:
|
| # Retries are annoying when commands fail for legitimate reasons. Might want
|
| # to enable them if this is ever used on bots though.
|
| - device = device_utils.DeviceUtils(args.device, default_retries=0)
|
| + device = device_utils.DeviceUtils(
|
| + args.device, default_retries=0, enable_device_files_cache=True)
|
| else:
|
| - devices = device_utils.DeviceUtils.HealthyDevices(default_retries=0)
|
| + devices = device_utils.DeviceUtils.HealthyDevices(
|
| + default_retries=0, enable_device_files_cache=True)
|
| if not devices:
|
| raise device_errors.NoDevicesError()
|
| elif len(devices) == 1:
|
| @@ -111,12 +126,6 @@ def main():
|
| logging.info('Uninstall took %s seconds.', main_timer.GetDelta())
|
| return
|
|
|
| - if device.build_version_sdk >= version_codes.MARSHMALLOW:
|
| - if apk_help.HasIsolatedProcesses():
|
| - raise Exception('Cannot use perform incremental installs on Android M+ '
|
| - 'without first disabling isolated processes. Use GN arg: '
|
| - 'disable_incremental_isolated_processes=true to do so.')
|
| -
|
| # Install .apk(s) if any of them have changed.
|
| def do_install():
|
| install_timer.Start()
|
| @@ -153,6 +162,29 @@ def main():
|
| delete_device_stale=True)
|
| push_dex_timer.Stop(log=False)
|
|
|
| + def check_sdk_version():
|
| + if device.build_version_sdk >= version_codes.MARSHMALLOW:
|
| + if apk_help.HasIsolatedProcesses():
|
| + raise Exception('Cannot use perform incremental installs on Android M+ '
|
| + 'without first disabling isolated processes.\n'
|
| + 'To do so, use GN arg:\n'
|
| + ' disable_incremental_isolated_processes=true')
|
| +
|
| + cache_path = '%s/files-cache.json' % device_incremental_dir
|
| + def restore_cache():
|
| + # 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])
|
| + else:
|
| + logging.info('Device cache not found: %s', cache_path)
|
| +
|
| + def save_cache():
|
| + cache_data = device.DumpCacheData()
|
| + device.WriteFile(cache_path, cache_data)
|
| +
|
| # Create 2 lock files:
|
| # * install.lock tells the app to pause on start-up (until we release it).
|
| # * firstrun.lock is used by the app to pause all secondary processes until
|
| @@ -169,19 +201,21 @@ def main():
|
| device.RunShellCommand('echo > %s/install.lock' % device_incremental_dir,
|
| check_return=True)
|
|
|
| - create_lock_files()
|
| # Concurrency here speeds things up quite a bit, but DeviceUtils hasn't
|
| # been designed for multi-threading. Enabling only because this is a
|
| # developer-only tool.
|
| - if args.no_threading:
|
| - do_install()
|
| - do_push_files()
|
| - else:
|
| - reraiser_thread.RunAsync((do_install, do_push_files))
|
| - release_installer_lock()
|
| - logging.info('Took %s seconds (install=%s, libs=%s, dex=%s)',
|
| - main_timer.GetDelta(), install_timer.GetDelta(),
|
| - push_native_timer.GetDelta(), push_dex_timer.GetDelta())
|
| + setup_timer = _Execute(
|
| + args.threading, create_lock_files, restore_cache, check_sdk_version)
|
| +
|
| + _Execute(args.threading, do_install, do_push_files)
|
| +
|
| + finalize_timer = _Execute(args.threading, release_installer_lock, save_cache)
|
| +
|
| + logging.info(
|
| + 'Took %s seconds (setup=%s, install=%s, libs=%s, dex=%s, finalize=%s)',
|
| + main_timer.GetDelta(), setup_timer.GetDelta(), install_timer.GetDelta(),
|
| + push_native_timer.GetDelta(), push_dex_timer.GetDelta(),
|
| + finalize_timer.GetDelta())
|
|
|
|
|
| if __name__ == '__main__':
|
|
|