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