| # Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| |
| # pylint: disable=W0201 |
| |
| |
| from recipe_engine import recipe_api |
| |
| from . import android |
| from . import chromebook |
| from . import default |
| from . import docker |
| from . import ios |
| from . import valgrind |
| from . import win_ssh |
| |
| |
| """Abstractions for running code on various platforms. |
| |
| The methods in this module define how certain high-level functions should work. |
| Each flavor should correspond to a subclass of DefaultFlavor which may override |
| any of these functions as appropriate for that flavor. |
| |
| For example, the AndroidFlavor will override the functions for copying files |
| between the host and Android device, as well as the 'step' function, so that |
| commands may be run through ADB. |
| """ |
| |
| |
| VERSION_FILE_LOTTIE = 'LOTTIE_VERSION' |
| VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION' |
| VERSION_FILE_SKP = 'SKP_VERSION' |
| VERSION_FILE_SVG = 'SVG_VERSION' |
| VERSION_FILE_MSKP = 'MSKP_VERSION' |
| VERSION_FILE_TEXTTRACES = 'TEXTTRACES_VERSION' |
| |
| VERSION_NONE = -1 |
| |
| def is_android(vars_api): |
| return ('Android' in vars_api.extra_tokens or |
| 'Android' in vars_api.builder_cfg.get('os', '')) |
| |
| def is_chromebook(vars_api): |
| return ('Chromebook' in vars_api.extra_tokens or |
| 'ChromeOS' in vars_api.builder_cfg.get('os', '')) |
| |
| def is_docker(vars_api): |
| return 'Docker' in vars_api.extra_tokens |
| |
| def is_ios(vars_api): |
| return ('iOS' in vars_api.extra_tokens or |
| 'iOS' == vars_api.builder_cfg.get('os', '')) |
| |
| def is_test_skqp(vars_api): |
| return ('SKQP' in vars_api.extra_tokens and |
| vars_api.builder_name.startswith('Test')) |
| |
| def is_valgrind(vars_api): |
| return 'Valgrind' in vars_api.extra_tokens |
| |
| def is_win_ssh(vars_api): |
| return 'LenovoYogaC630' in vars_api.builder_cfg.get('model', '') |
| |
| |
| class SkiaFlavorApi(recipe_api.RecipeApi): |
| def get_flavor(self, vars_api, app_name): |
| """Return a flavor utils object specific to the given builder.""" |
| if is_chromebook(vars_api): |
| return chromebook.ChromebookFlavor(self, app_name) |
| if is_android(vars_api) and not is_test_skqp(vars_api): |
| return android.AndroidFlavor(self, app_name) |
| elif is_docker(vars_api): |
| return docker.DockerFlavor(self, app_name) |
| elif is_ios(vars_api): |
| return ios.iOSFlavor(self, app_name) |
| elif is_valgrind(vars_api): |
| return valgrind.ValgrindFlavor(self, app_name) |
| elif is_win_ssh(vars_api): |
| return win_ssh.WinSSHFlavor(self, app_name) |
| else: |
| return default.DefaultFlavor(self, app_name) |
| |
| def setup(self, app_name): |
| self._f = self.get_flavor(self.m.vars, app_name) |
| self.device_dirs = self._f.device_dirs |
| self.host_dirs = self._f.host_dirs |
| self._skia_dir = self.m.path['start_dir'].join('skia') |
| |
| def step(self, name, cmd, **kwargs): |
| return self._f.step(name, cmd, **kwargs) |
| |
| def device_path_join(self, *args): |
| return self._f.device_path_join(*args) |
| |
| def copy_directory_contents_to_device(self, host_dir, device_dir): |
| return self._f.copy_directory_contents_to_device(host_dir, device_dir) |
| |
| def copy_directory_contents_to_host(self, device_dir, host_dir): |
| return self._f.copy_directory_contents_to_host(device_dir, host_dir) |
| |
| def copy_file_to_device(self, host_path, device_path): |
| return self._f.copy_file_to_device(host_path, device_path) |
| |
| def create_clean_host_dir(self, path): |
| return self._f.create_clean_host_dir(path) |
| |
| def create_clean_device_dir(self, path): |
| return self._f.create_clean_device_dir(path) |
| |
| def read_file_on_device(self, path, **kwargs): |
| return self._f.read_file_on_device(path, **kwargs) |
| |
| def remove_file_on_device(self, path): |
| return self._f.remove_file_on_device(path) |
| |
| def install(self, skps=False, images=False, lotties=False, svgs=False, |
| resources=False, mskps=False, texttraces=False): |
| self._f.install() |
| |
| if texttraces: |
| self._copy_texttraces() |
| # TODO(borenet): Only copy files which have changed. |
| if resources: |
| self.copy_directory_contents_to_device( |
| self.m.path['start_dir'].join('skia', 'resources'), |
| self.device_dirs.resource_dir) |
| |
| if skps: |
| self._copy_skps() |
| if images: |
| self._copy_images() |
| if lotties: |
| self._copy_lotties() |
| if svgs: |
| self._copy_svgs() |
| if mskps: |
| self._copy_mskps() |
| |
| def cleanup_steps(self): |
| return self._f.cleanup_steps() |
| |
| def _copy_dir(self, host_version, version_file, tmp_dir, |
| host_path, device_path): |
| actual_version_file = self.m.path.join(tmp_dir, version_file) |
| # Copy to device. |
| device_version_file = self.device_path_join( |
| self.device_dirs.tmp_dir, version_file) |
| if str(actual_version_file) != str(device_version_file): |
| device_version = self.read_file_on_device(device_version_file, |
| abort_on_failure=False, |
| fail_build_on_failure=False) |
| if not device_version: |
| device_version = VERSION_NONE |
| if device_version != host_version: |
| self.remove_file_on_device(device_version_file) |
| self.create_clean_device_dir(device_path) |
| self.copy_directory_contents_to_device( |
| host_path, device_path) |
| |
| # Copy the new version file. |
| self.copy_file_to_device(actual_version_file, device_version_file) |
| |
| def _copy_images(self): |
| """Copy test images if needed.""" |
| version = self.m.run.asset_version('skimage', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SK_IMAGE), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_SK_IMAGE, |
| self.m.vars.tmp_dir, |
| self.host_dirs.images_dir, |
| self.device_dirs.images_dir) |
| return version |
| |
| def _copy_lotties(self): |
| """Copy test lotties if needed.""" |
| version = self.m.run.asset_version('lottie-samples', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_LOTTIE), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_LOTTIE, |
| self.m.vars.tmp_dir, |
| self.host_dirs.lotties_dir, |
| self.device_dirs.lotties_dir) |
| return version |
| |
| def _copy_skps(self): |
| """Copy the SKPs if needed.""" |
| version = self.m.run.asset_version('skp', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SKP), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_SKP, |
| self.m.vars.tmp_dir, |
| self.host_dirs.skp_dir, |
| self.device_dirs.skp_dir) |
| return version |
| |
| def _copy_svgs(self): |
| """Copy the SVGs if needed.""" |
| version = self.m.run.asset_version('svg', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SVG), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_SVG, |
| self.m.vars.tmp_dir, |
| self.host_dirs.svg_dir, |
| self.device_dirs.svg_dir) |
| return version |
| |
| def _copy_mskps(self): |
| """Copy the MSKPs if needed.""" |
| version = self.m.run.asset_version('mskp', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_MSKP), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_MSKP, |
| self.m.vars.tmp_dir, |
| self.host_dirs.mskp_dir, |
| self.device_dirs.mskp_dir) |
| return version |
| |
| def _copy_texttraces(self): |
| """Copy the text traces if needed.""" |
| version = self.m.run.asset_version('text_blob_traces', self._skia_dir) |
| self.m.run.writefile( |
| self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_TEXTTRACES), |
| version) |
| self._copy_dir( |
| version, |
| VERSION_FILE_TEXTTRACES, |
| self.m.vars.tmp_dir, |
| self.host_dirs.texttraces_dir, |
| self.device_dirs.texttraces_dir) |
| return version |