1# Copyright 2016 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5 6# pylint: disable=W0201 7 8 9from recipe_engine import recipe_api 10 11from . import android 12from . import chromebook 13from . import chromecast 14from . import default 15from . import ios 16from . import valgrind 17 18 19"""Abstractions for running code on various platforms. 20 21The methods in this module define how certain high-level functions should work. 22Each flavor should correspond to a subclass of DefaultFlavor which may override 23any of these functions as appropriate for that flavor. 24 25For example, the AndroidFlavor will override the functions for copying files 26between the host and Android device, as well as the 'step' function, so that 27commands may be run through ADB. 28""" 29 30 31VERSION_FILE_LOTTIE = 'LOTTIE_VERSION' 32VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION' 33VERSION_FILE_SKP = 'SKP_VERSION' 34VERSION_FILE_SVG = 'SVG_VERSION' 35 36VERSION_NONE = -1 37 38def is_android(vars_api): 39 return 'Android' in vars_api.extra_tokens 40 41def is_chromecast(vars_api): 42 return ('Chromecast' in vars_api.extra_tokens or 43 'Chromecast' in vars_api.builder_cfg.get('os', '')) 44 45def is_chromebook(vars_api): 46 return ('Chromebook' in vars_api.extra_tokens or 47 'ChromeOS' in vars_api.builder_cfg.get('os', '')) 48 49def is_ios(vars_api): 50 return ('iOS' in vars_api.extra_tokens or 51 'iOS' == vars_api.builder_cfg.get('os', '')) 52 53def is_test_skqp(vars_api): 54 return ('SKQP' in vars_api.extra_tokens and 55 vars_api.builder_name.startswith('Test')) 56 57def is_valgrind(vars_api): 58 return 'Valgrind' in vars_api.extra_tokens 59 60 61class SkiaFlavorApi(recipe_api.RecipeApi): 62 def get_flavor(self, vars_api): 63 """Return a flavor utils object specific to the given builder.""" 64 if is_chromecast(vars_api): 65 return chromecast.ChromecastFlavor(self) 66 if is_chromebook(vars_api): 67 return chromebook.ChromebookFlavor(self) 68 if is_android(vars_api) and not is_test_skqp(vars_api): 69 return android.AndroidFlavor(self) 70 elif is_ios(vars_api): 71 return ios.iOSFlavor(self) 72 elif is_valgrind(vars_api): 73 return valgrind.ValgrindFlavor(self) 74 else: 75 return default.DefaultFlavor(self) 76 77 def setup(self): 78 self._f = self.get_flavor(self.m.vars) 79 self.device_dirs = self._f.device_dirs 80 self.host_dirs = self._f.host_dirs 81 self._skia_dir = self.m.path['start_dir'].join('skia') 82 83 def step(self, name, cmd, **kwargs): 84 return self._f.step(name, cmd, **kwargs) 85 86 def device_path_join(self, *args): 87 return self._f.device_path_join(*args) 88 89 def copy_directory_contents_to_device(self, host_dir, device_dir): 90 return self._f.copy_directory_contents_to_device(host_dir, device_dir) 91 92 def copy_directory_contents_to_host(self, device_dir, host_dir): 93 return self._f.copy_directory_contents_to_host(device_dir, host_dir) 94 95 def copy_file_to_device(self, host_path, device_path): 96 return self._f.copy_file_to_device(host_path, device_path) 97 98 def create_clean_host_dir(self, path): 99 return self._f.create_clean_host_dir(path) 100 101 def create_clean_device_dir(self, path): 102 return self._f.create_clean_device_dir(path) 103 104 def read_file_on_device(self, path, **kwargs): 105 return self._f.read_file_on_device(path, **kwargs) 106 107 def remove_file_on_device(self, path): 108 return self._f.remove_file_on_device(path) 109 110 def install(self, skps=False, images=False, lotties=False, svgs=False, 111 resources=False): 112 self._f.install() 113 114 # TODO(borenet): Only copy files which have changed. 115 if resources: 116 self.copy_directory_contents_to_device( 117 self.m.path['start_dir'].join('skia', 'resources'), 118 self.device_dirs.resource_dir) 119 120 if skps: 121 self._copy_skps() 122 if images: 123 self._copy_images() 124 if lotties: 125 self._copy_lotties() 126 if svgs: 127 self._copy_svgs() 128 129 def cleanup_steps(self): 130 return self._f.cleanup_steps() 131 132 def _copy_dir(self, host_version, version_file, tmp_dir, 133 host_path, device_path): 134 actual_version_file = self.m.path.join(tmp_dir, version_file) 135 # Copy to device. 136 device_version_file = self.device_path_join( 137 self.device_dirs.tmp_dir, version_file) 138 if str(actual_version_file) != str(device_version_file): 139 device_version = self.read_file_on_device(device_version_file, 140 abort_on_failure=False, 141 fail_build_on_failure=False) 142 if not device_version: 143 device_version = VERSION_NONE 144 if device_version != host_version: 145 self.remove_file_on_device(device_version_file) 146 self.create_clean_device_dir(device_path) 147 self.copy_directory_contents_to_device( 148 host_path, device_path) 149 150 # Copy the new version file. 151 self.copy_file_to_device(actual_version_file, device_version_file) 152 153 def _copy_images(self): 154 """Copy test images if needed.""" 155 version = self.m.run.asset_version('skimage', self._skia_dir) 156 self.m.run.writefile( 157 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SK_IMAGE), 158 version) 159 self._copy_dir( 160 version, 161 VERSION_FILE_SK_IMAGE, 162 self.m.vars.tmp_dir, 163 self.host_dirs.images_dir, 164 self.device_dirs.images_dir) 165 return version 166 167 def _copy_lotties(self): 168 """Copy test lotties if needed.""" 169 version = self.m.run.asset_version('lottie-samples', self._skia_dir) 170 self.m.run.writefile( 171 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_LOTTIE), 172 version) 173 self._copy_dir( 174 version, 175 VERSION_FILE_LOTTIE, 176 self.m.vars.tmp_dir, 177 self.host_dirs.lotties_dir, 178 self.device_dirs.lotties_dir) 179 return version 180 181 def _copy_skps(self): 182 """Copy the SKPs if needed.""" 183 version = self.m.run.asset_version('skp', self._skia_dir) 184 self.m.run.writefile( 185 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SKP), 186 version) 187 self._copy_dir( 188 version, 189 VERSION_FILE_SKP, 190 self.m.vars.tmp_dir, 191 self.host_dirs.skp_dir, 192 self.device_dirs.skp_dir) 193 return version 194 195 def _copy_svgs(self): 196 """Copy the SVGs if needed.""" 197 version = self.m.run.asset_version('svg', self._skia_dir) 198 self.m.run.writefile( 199 self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SVG), 200 version) 201 self._copy_dir( 202 version, 203 VERSION_FILE_SVG, 204 self.m.vars.tmp_dir, 205 self.host_dirs.svg_dir, 206 self.device_dirs.svg_dir) 207 return version 208