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

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

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

Powered by Google App Engine
This is Rietveld 408576698