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 default_flavor
12from . import flutter_flavor
13from . import gn_android_flavor
14from . import gn_chromecast_flavor
15from . import gn_flavor
16from . import ios_flavor
17from . import pdfium_flavor
18from . import valgrind_flavor
19
20
21TEST_EXPECTED_SKP_VERSION = '42'
22TEST_EXPECTED_SVG_VERSION = '42'
23TEST_EXPECTED_SK_IMAGE_VERSION = '42'
24
25VERSION_FILE_SK_IMAGE = 'SK_IMAGE_VERSION'
26VERSION_FILE_SKP = 'SKP_VERSION'
27VERSION_FILE_SVG = 'SVG_VERSION'
28
29VERSION_NONE = -1
30
31def is_android(builder_cfg):
32  return 'Android' in builder_cfg.get('extra_config', '')
33
34def is_chromecast(builder_cfg):
35  return ('Chromecast' in builder_cfg.get('extra_config', '') or
36          'Chromecast' in builder_cfg.get('os', ''))
37
38def is_flutter(builder_cfg):
39  return 'Flutter' in builder_cfg.get('extra_config', '')
40
41def is_ios(builder_cfg):
42  return 'iOS' == builder_cfg.get('os', '')
43
44def is_pdfium(builder_cfg):
45  return 'PDFium' in builder_cfg.get('extra_config', '')
46
47def is_valgrind(builder_cfg):
48  return 'Valgrind' in builder_cfg.get('extra_config', '')
49
50
51class SkiaFlavorApi(recipe_api.RecipeApi):
52  def get_flavor(self, builder_cfg):
53    """Return a flavor utils object specific to the given builder."""
54    if is_flutter(builder_cfg):
55      return flutter_flavor.FlutterFlavorUtils(self.m)
56    if is_chromecast(builder_cfg):
57      return gn_chromecast_flavor.GNChromecastFlavorUtils(self.m)
58    if is_android(builder_cfg):
59      return gn_android_flavor.GNAndroidFlavorUtils(self.m)
60    elif is_ios(builder_cfg):
61      return ios_flavor.iOSFlavorUtils(self.m)
62    elif is_pdfium(builder_cfg):
63      return pdfium_flavor.PDFiumFlavorUtils(self.m)
64    elif is_valgrind(builder_cfg):
65      return valgrind_flavor.ValgrindFlavorUtils(self.m)
66    else:
67      return gn_flavor.GNFlavorUtils(self.m)
68
69  def setup(self):
70    self._f = self.get_flavor(self.m.vars.builder_cfg)
71
72  def step(self, name, cmd, **kwargs):
73    return self._f.step(name, cmd, **kwargs)
74
75  def compile(self, target):
76    return self._f.compile(target)
77
78  def copy_extra_build_products(self, swarming_out_dir):
79    return self._f.copy_extra_build_products(swarming_out_dir)
80
81  @property
82  def out_dir(self):
83    return self._f.out_dir
84
85  def device_path_join(self, *args):
86    return self._f.device_path_join(*args)
87
88  def copy_directory_contents_to_device(self, host_dir, device_dir):
89    return self._f.copy_directory_contents_to_device(host_dir, device_dir)
90
91  def copy_directory_contents_to_host(self, device_dir, host_dir):
92    return self._f.copy_directory_contents_to_host(device_dir, host_dir)
93
94  def copy_file_to_device(self, host_path, device_path):
95    return self._f.copy_file_to_device(host_path, device_path)
96
97  def create_clean_host_dir(self, path):
98    return self._f.create_clean_host_dir(path)
99
100  def create_clean_device_dir(self, path):
101    return self._f.create_clean_device_dir(path)
102
103  def read_file_on_device(self, path):
104    return self._f.read_file_on_device(path)
105
106  def remove_file_on_device(self, path):
107    return self._f.remove_file_on_device(path)
108
109  def install_everything(self):
110    self.install(skps=True, images=True, svgs=True, resources=True)
111
112  def install(self, skps=False, images=False, svgs=False, resources=False):
113    self._f.install()
114    self.device_dirs = self._f.device_dirs
115
116    # TODO(borenet): Only copy files which have changed.
117    if resources:
118      self.copy_directory_contents_to_device(
119          self.m.vars.resource_dir,
120          self.device_dirs.resource_dir)
121
122    if skps:
123      self._copy_skps()
124    if images:
125      self._copy_images()
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, test_expected_version,
134                test_actual_version):
135    actual_version_file = self.m.path.join(tmp_dir, version_file)
136    # Copy to device.
137    device_version_file = self.device_path_join(
138        self.device_dirs.tmp_dir, version_file)
139    if str(actual_version_file) != str(device_version_file):
140      try:
141        device_version = self.read_file_on_device(device_version_file)
142      except self.m.step.StepFailure:   # pragma: nocover
143        device_version = VERSION_NONE   # pragma: nocover
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    """Download and copy test images if needed."""
155    version_file = self.m.vars.infrabots_dir.join(
156        'assets', 'skimage', 'VERSION')
157    test_data = self.m.properties.get(
158        'test_downloaded_sk_image_version', TEST_EXPECTED_SK_IMAGE_VERSION)
159    version = self.m.run.readfile(
160        version_file,
161        name='Get downloaded skimage VERSION',
162        test_data=test_data).rstrip()
163    self.m.run.writefile(
164        self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SK_IMAGE),
165        version)
166    self._copy_dir(
167        version,
168        VERSION_FILE_SK_IMAGE,
169        self.m.vars.tmp_dir,
170        self.m.vars.images_dir,
171        self.device_dirs.images_dir,
172        test_expected_version=self.m.properties.get(
173            'test_downloaded_sk_image_version',
174            TEST_EXPECTED_SK_IMAGE_VERSION),
175        test_actual_version=self.m.properties.get(
176            'test_downloaded_sk_image_version',
177            TEST_EXPECTED_SK_IMAGE_VERSION))
178    return version
179
180  def _copy_skps(self):
181    """Download and copy the SKPs if needed."""
182    version_file = self.m.vars.infrabots_dir.join(
183        'assets', 'skp', 'VERSION')
184    test_data = self.m.properties.get(
185        'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION)
186    version = self.m.run.readfile(
187        version_file,
188        name='Get downloaded SKP VERSION',
189        test_data=test_data).rstrip()
190    self.m.run.writefile(
191        self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SKP),
192        version)
193    self._copy_dir(
194        version,
195        VERSION_FILE_SKP,
196        self.m.vars.tmp_dir,
197        self.m.vars.local_skp_dir,
198        self.device_dirs.skp_dir,
199        test_expected_version=self.m.properties.get(
200            'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION),
201        test_actual_version=self.m.properties.get(
202            'test_downloaded_skp_version', TEST_EXPECTED_SKP_VERSION))
203    return version
204
205  def _copy_svgs(self):
206    """Download and copy the SVGs if needed."""
207    version_file = self.m.vars.infrabots_dir.join(
208        'assets', 'svg', 'VERSION')
209    test_data = self.m.properties.get(
210        'test_downloaded_svg_version', TEST_EXPECTED_SVG_VERSION)
211    version = self.m.run.readfile(
212        version_file,
213        name='Get downloaded SVG VERSION',
214        test_data=test_data).rstrip()
215    self.m.run.writefile(
216        self.m.path.join(self.m.vars.tmp_dir, VERSION_FILE_SVG),
217        version)
218    self._copy_dir(
219        version,
220        VERSION_FILE_SVG,
221        self.m.vars.tmp_dir,
222        self.m.vars.local_svg_dir,
223        self.device_dirs.svg_dir,
224        test_expected_version=self.m.properties.get(
225            'test_downloaded_svg_version', TEST_EXPECTED_SVG_VERSION),
226        test_actual_version=self.m.properties.get(
227            'test_downloaded_svg_version', TEST_EXPECTED_SVG_VERSION))
228    return version
229