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