Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: infra/bots/recipe_modules/skia/android_flavor.py

Issue 2198173002: Re-organize Skia recipes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix missing dependency Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2014 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
9 import android_devices
10 import copy
11 import default_flavor
12
13
14 """Android flavor utils, used for building for and running tests on Android."""
15
16
17 class _ADBWrapper(object):
18 """Wrapper for the ADB recipe module.
19
20 The ADB recipe module looks for the ADB binary at a path we don't have checked
21 out on our bots. This wrapper ensures that we set a custom ADB path before
22 attempting to use the module.
23 """
24 def __init__(self, adb_api, path_to_adb, serial_args, android_flavor):
25 self._adb = adb_api
26 self._adb.set_adb_path(path_to_adb)
27 self._has_root = False # This is set in install().
28 self._serial_args = serial_args
29 self._wait_count = 0
30 self._android_flavor = android_flavor
31
32 def wait_for_device(self):
33 """Run 'adb wait-for-device'."""
34 self._wait_count += 1
35 cmd = [
36 self._android_flavor.android_bin.join('adb_wait_for_device')
37 ] + self._serial_args
38 self._android_flavor._skia_api.run(
39 self._android_flavor._skia_api.m.step,
40 name='wait for device (%d)' % self._wait_count,
41 cmd=cmd,
42 env=self._android_flavor._default_env,
43 infra_step=True)
44
45 cmd = [
46 self._android_flavor.android_bin.join('adb_wait_for_charge'),
47 ] + self._serial_args
48 self._android_flavor._skia_api.run(
49 self._android_flavor._skia_api.m.step,
50 name='wait for charge (%d)' % self._wait_count,
51 cmd=cmd,
52 env=self._android_flavor._default_env,
53 infra_step=True)
54
55 def maybe_wait_for_device(self):
56 """Run 'adb wait-for-device' if it hasn't already been run."""
57 if self._wait_count == 0:
58 self.wait_for_device()
59
60 def __call__(self, *args, **kwargs):
61 self.maybe_wait_for_device()
62 return self._android_flavor._skia_api.run(self._adb, *args, **kwargs)
63
64
65 class AndroidFlavorUtils(default_flavor.DefaultFlavorUtils):
66 def __init__(self, skia_api):
67 super(AndroidFlavorUtils, self).__init__(skia_api)
68 self.device = self._skia_api.builder_spec['device_cfg']
69 self.android_bin = self._skia_api.skia_dir.join(
70 'platform_tools', 'android', 'bin')
71 self._android_sdk_root = self._skia_api.slave_dir.join(
72 'android_sdk', 'android-sdk')
73 self.serial = None
74 self.serial_args = []
75 try:
76 path_to_adb = self._skia_api.m.step(
77 'which adb',
78 cmd=['which', 'adb'],
79 stdout=self._skia_api.m.raw_io.output(),
80 infra_step=True).stdout.rstrip()
81 except self._skia_api.m.step.StepFailure:
82 path_to_adb = self._skia_api.m.path.join(self._android_sdk_root,
83 'platform-tools', 'adb')
84 self._adb = _ADBWrapper(
85 self._skia_api.m.adb, path_to_adb, self.serial_args, self)
86 self._default_env = {'ANDROID_SDK_ROOT': self._android_sdk_root,
87 'ANDROID_HOME': self._android_sdk_root,
88 'SKIA_ANDROID_VERBOSE_SETUP': 1}
89
90 def step(self, name, cmd, env=None, **kwargs):
91 self._adb.maybe_wait_for_device()
92 args = [
93 self.android_bin.join('android_run_skia'),
94 '--verbose',
95 '--logcat',
96 '-d', self.device,
97 ] + self.serial_args + [
98 '-t', self._skia_api.configuration,
99 ]
100 env = dict(env or {})
101 env.update(self._default_env)
102
103 return self._skia_api.run(self._skia_api.m.step, name=name, cmd=args + cmd,
104 env=env, **kwargs)
105
106 def compile(self, target):
107 """Build the given target."""
108 env = dict(self._default_env)
109 ccache = self._skia_api.ccache()
110 if ccache:
111 env['ANDROID_MAKE_CCACHE'] = ccache
112
113 cmd = [self.android_bin.join('android_ninja'), target, '-d', self.device]
114 if 'Clang' in self._skia_api.builder_name:
115 cmd.append('--clang')
116 if 'GCC' in self._skia_api.builder_name:
117 cmd.append('--gcc')
118 if 'Vulkan' in self._skia_api.builder_name:
119 cmd.append('--vulkan')
120 self._skia_api.run(self._skia_api.m.step, 'build %s' % target, cmd=cmd,
121 env=env, cwd=self._skia_api.m.path['checkout'])
122
123 def device_path_join(self, *args):
124 """Like os.path.join(), but for paths on a connected Android device."""
125 return '/'.join(args)
126
127 def device_path_exists(self, path):
128 """Like os.path.exists(), but for paths on a connected device."""
129 exists_str = 'FILE_EXISTS'
130 return exists_str in self._adb(
131 name='exists %s' % self._skia_api.m.path.basename(path),
132 serial=self.serial,
133 cmd=['shell', 'if', '[', '-e', path, '];',
134 'then', 'echo', exists_str + ';', 'fi'],
135 stdout=self._skia_api.m.raw_io.output(),
136 infra_step=True
137 ).stdout
138
139 def _remove_device_dir(self, path):
140 """Remove the directory on the device."""
141 self._adb(name='rmdir %s' % self._skia_api.m.path.basename(path),
142 serial=self.serial,
143 cmd=['shell', 'rm', '-r', path],
144 infra_step=True)
145 # Sometimes the removal fails silently. Verify that it worked.
146 if self.device_path_exists(path):
147 raise Exception('Failed to remove %s!' % path) # pragma: no cover
148
149 def _create_device_dir(self, path):
150 """Create the directory on the device."""
151 self._adb(name='mkdir %s' % self._skia_api.m.path.basename(path),
152 serial=self.serial,
153 cmd=['shell', 'mkdir', '-p', path],
154 infra_step=True)
155
156 def copy_directory_contents_to_device(self, host_dir, device_dir):
157 """Like shutil.copytree(), but for copying to a connected device."""
158 self._skia_api.run(
159 self._skia_api.m.step,
160 name='push %s' % self._skia_api.m.path.basename(host_dir),
161 cmd=[
162 self.android_bin.join('adb_push_if_needed'), '--verbose',
163 ] + self.serial_args + [
164 host_dir, device_dir,
165 ],
166 env=self._default_env,
167 infra_step=True)
168
169 def copy_directory_contents_to_host(self, device_dir, host_dir):
170 """Like shutil.copytree(), but for copying from a connected device."""
171 self._skia_api.run(
172 self._skia_api.m.step,
173 name='pull %s' % self._skia_api.m.path.basename(device_dir),
174 cmd=[
175 self.android_bin.join('adb_pull_if_needed'), '--verbose',
176 ] + self.serial_args + [
177 device_dir, host_dir,
178 ],
179 env=self._default_env,
180 infra_step=True)
181
182 def copy_file_to_device(self, host_path, device_path):
183 """Like shutil.copyfile, but for copying to a connected device."""
184 self._adb(name='push %s' % self._skia_api.m.path.basename(host_path),
185 serial=self.serial,
186 cmd=['push', host_path, device_path],
187 infra_step=True)
188
189 def create_clean_device_dir(self, path):
190 """Like shutil.rmtree() + os.makedirs(), but on a connected device."""
191 self._remove_device_dir(path)
192 self._create_device_dir(path)
193
194 def has_root(self):
195 """Determine if we have root access on this device."""
196 # Special case: GalaxyS3 hangs on `adb root`. Don't bother.
197 if 'GalaxyS3' in self._skia_api.builder_name:
198 return False
199
200 # Determine if we have root access.
201 has_root = False
202 try:
203 output = self._adb(name='adb root',
204 serial=self.serial,
205 cmd=['root'],
206 stdout=self._skia_api.m.raw_io.output(),
207 infra_step=True).stdout.rstrip()
208 if ('restarting adbd as root' in output or
209 'adbd is already running as root' in output):
210 has_root = True
211 except self._skia_api.m.step.StepFailure: # pragma: nocover
212 pass
213 # Wait for the device to reconnect.
214 self._skia_api.run(
215 self._skia_api.m.step,
216 name='wait',
217 cmd=['sleep', '10'],
218 infra_step=True)
219 self._adb.wait_for_device()
220 return has_root
221
222 def install(self):
223 """Run device-specific installation steps."""
224 self._has_root = self.has_root()
225 self._skia_api.run(self._skia_api.m.step,
226 name='kill skia',
227 cmd=[
228 self.android_bin.join('android_kill_skia'),
229 '--verbose',
230 ] + self.serial_args,
231 env=self._default_env,
232 infra_step=True)
233 if self._has_root:
234 self._adb(name='stop shell',
235 serial=self.serial,
236 cmd=['shell', 'stop'],
237 infra_step=True)
238
239 # Print out battery stats.
240 self._adb(name='starting battery stats',
241 serial=self.serial,
242 cmd=['shell', 'dumpsys', 'batteryproperties'],
243 infra_step=True)
244
245 # Print out CPU scale info.
246 if self._has_root:
247 self._adb(name='cat scaling_governor',
248 serial=self.serial,
249 cmd=['shell', 'cat',
250 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'],
251 infra_step=True)
252 self._adb(name='cat cpu_freq',
253 serial=self.serial,
254 cmd=['shell', 'cat',
255 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'],
256 infra_step=True)
257
258 def cleanup_steps(self):
259 """Run any device-specific cleanup steps."""
260 if self._skia_api.do_test_steps or self._skia_api.do_perf_steps:
261 self._adb(name='final battery stats',
262 serial=self.serial,
263 cmd=['shell', 'dumpsys', 'batteryproperties'],
264 infra_step=True)
265 self._adb(name='reboot',
266 serial=self.serial,
267 cmd=['reboot'],
268 infra_step=True)
269 self._skia_api.run(
270 self._skia_api.m.step,
271 name='wait for reboot',
272 cmd=['sleep', '10'],
273 infra_step=True)
274 self._adb.wait_for_device()
275 # The ADB binary conflicts with py-adb used by swarming. Kill it
276 # when finished to play nice.
277 self._adb(name='kill-server',
278 serial=self.serial,
279 cmd=['kill-server'],
280 infra_step=True)
281
282 def read_file_on_device(self, path, *args, **kwargs):
283 """Read the given file."""
284 return self._adb(name='read %s' % self._skia_api.m.path.basename(path),
285 serial=self.serial,
286 cmd=['shell', 'cat', path],
287 stdout=self._skia_api.m.raw_io.output(),
288 infra_step=True).stdout.rstrip()
289
290 def remove_file_on_device(self, path, *args, **kwargs):
291 """Delete the given file."""
292 return self._adb(name='rm %s' % self._skia_api.m.path.basename(path),
293 serial=self.serial,
294 cmd=['shell', 'rm', '-f', path],
295 infra_step=True,
296 *args,
297 **kwargs)
298
299 def get_device_dirs(self):
300 """ Set the directories which will be used by the build steps."""
301 device_scratch_dir = self._adb(
302 name='get EXTERNAL_STORAGE dir',
303 serial=self.serial,
304 cmd=['shell', 'echo', '$EXTERNAL_STORAGE'],
305 stdout=self._skia_api.m.raw_io.output(),
306 infra_step=True,
307 ).stdout.rstrip()
308 prefix = self.device_path_join(device_scratch_dir, 'skiabot', 'skia_')
309 return default_flavor.DeviceDirs(
310 dm_dir=prefix + 'dm',
311 perf_data_dir=prefix + 'perf',
312 resource_dir=prefix + 'resources',
313 images_dir=prefix + 'images',
314 skp_dir=prefix + 'skp/skps',
315 tmp_dir=prefix + 'tmp_dir')
316
OLDNEW
« no previous file with comments | « infra/bots/recipe_modules/skia/android_devices.py ('k') | infra/bots/recipe_modules/skia/api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698