Flutter Engine
The Flutter Engine
Public Member Functions | Public Attributes | List of all members
flavor.android.AndroidFlavor Class Reference
Inheritance diagram for flavor.android.AndroidFlavor:
flavor.default.DefaultFlavor

Public Member Functions

def __init__ (self, m, app_name)
 
def install (self)
 
def cleanup_steps (self)
 
def step (self, name, cmd)
 
def copy_file_to_device (self, host, device)
 
def copy_directory_contents_to_device (self, host, device)
 
def copy_directory_contents_to_host (self, device, host)
 
def read_file_on_device (self, path, **kwargs)
 
def remove_file_on_device (self, path)
 
def create_clean_device_dir (self, path)
 
- Public Member Functions inherited from flavor.default.DefaultFlavor
def __init__ (self, module, app_name)
 
def device_path_join (self, *args)
 
def copy_directory_contents_to_device (self, host_dir, device_dir)
 
def copy_directory_contents_to_host (self, device_dir, host_dir)
 
def copy_file_to_device (self, host_path, device_path)
 
def create_clean_device_dir (self, path)
 
def create_clean_host_dir (self, path)
 
def read_file_on_device (self, path, **kwargs)
 
def remove_file_on_device (self, path)
 
def install (self)
 
def cleanup_steps (self)
 
def step (self, name, cmd, **unused_kwargs)
 

Public Attributes

 ADB_BINARY
 
 ADB_PUB_KEY
 
 device_dirs
 
 cant_root
 
 cpus_to_scale
 
 disable_for_nanobench
 
 gpu_scaling
 
 app_name
 
- Public Attributes inherited from flavor.default.DefaultFlavor
 app_name
 
 module
 
 m
 
 device_dirs
 
 host_dirs
 

Detailed Description

Definition at line 16 of file android.py.

Constructor & Destructor Documentation

◆ __init__()

def flavor.android.AndroidFlavor.__init__ (   self,
  m,
  app_name 
)

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 17 of file android.py.

17 def __init__(self, m, app_name):
18 super(AndroidFlavor, self).__init__(m, app_name)
19 self._ever_ran_adb = False
20 self.ADB_BINARY = '/usr/bin/adb.1.0.35'
21 self.ADB_PUB_KEY = '/home/chrome-bot/.android/adbkey'
22 if 'skia' not in self.m.vars.swarming_bot_id:
23 self.ADB_BINARY = '/opt/infra-android/tools/adb'
24 self.ADB_PUB_KEY = ('/home/chrome-bot/.android/'
25 'chrome_infrastructure_adbkey')
26
27 # Data should go in android_data_dir, which may be preserved across runs.
28 android_data_dir = '/sdcard/revenge_of_the_skiabot/'
29 self.device_dirs = default.DeviceDirs(
30 bin_dir = '/data/local/tmp/',
31 dm_dir = android_data_dir + 'dm_out',
32 perf_data_dir = android_data_dir + 'perf',
33 resource_dir = android_data_dir + 'resources',
34 fonts_dir = 'NOT_SUPPORTED',
35 images_dir = android_data_dir + 'images',
36 lotties_dir = android_data_dir + 'lotties',
37 skp_dir = android_data_dir + 'skps',
38 svg_dir = android_data_dir + 'svgs',
39 tmp_dir = android_data_dir,
40 texttraces_dir = android_data_dir + 'text_blob_traces')
41
42 # A list of devices we can't root. If rooting fails and a device is not
43 # on the list, we fail the task to avoid perf inconsistencies.
44 self.cant_root = ['GalaxyS7_G930FD', 'GalaxyS9',
45 'GalaxyS20', 'MotoG4', 'NVIDIA_Shield',
46 'P30', 'Pixel4','Pixel4XL', 'Pixel5', 'TecnoSpark3Pro', 'JioNext']
47
48 # Maps device type -> CPU ids that should be scaled for nanobench.
49 # Many devices have two (or more) different CPUs (e.g. big.LITTLE
50 # on Nexus5x). The CPUs listed are the biggest cpus on the device.
51 # The CPUs are grouped together, so we only need to scale one of them
52 # (the one listed) in order to scale them all.
53 # E.g. Nexus5x has cpu0-3 as one chip and cpu4-5 as the other. Thus,
54 # if one wants to run a single-threaded application (e.g. nanobench), one
55 # can disable cpu0-3 and scale cpu 4 to have only cpu4 and 5 at the same
56 # frequency. See also disable_for_nanobench.
57 self.cpus_to_scale = {
58 'Nexus5x': [4],
59 'Pixel': [2],
60 'Pixel2XL': [4]
61 }
62
63 # Maps device type -> CPU ids that should be turned off when running
64 # single-threaded applications like nanobench. The devices listed have
65 # multiple, differnt CPUs. We notice a lot of noise that seems to be
66 # caused by nanobench running on the slow CPU, then the big CPU. By
67 # disabling this, we see less of that noise by forcing the same CPU
68 # to be used for the performance testing every time.
69 self.disable_for_nanobench = {
70 'Nexus5x': range(0, 4),
71 'Pixel': range(0, 2),
72 'Pixel2XL': range(0, 4),
73 'Pixel6': range(4,8), # Only use the 4 small cores.
74 'Pixel7': range(4,8),
75 }
76
77 self.gpu_scaling = {
78 "Nexus5": 450000000,
79 "Nexus5x": 600000000,
80 }
81

Member Function Documentation

◆ cleanup_steps()

def flavor.android.AndroidFlavor.cleanup_steps (   self)
Run any device-specific cleanup steps.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 289 of file android.py.

289 def cleanup_steps(self):
290 self.m.run(self.m.step,
291 'adb reboot device',
292 cmd=[self.ADB_BINARY, 'reboot'],
293 infra_step=True, timeout=30, abort_on_failure=False,
294 fail_build_on_failure=False)
295 self.m.run(self.m.step,
296 'wait for device after rebooting',
297 cmd=[
298 self.ADB_BINARY, 'wait-for-device', 'shell',
299 # Wait until the boot is actually complete.
300 # https://android.stackexchange.com/a/164050
301 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done',
302 ],
303 timeout=180, abort_on_failure=False,
304 fail_build_on_failure=False)
305
306 if 'ASAN' in self.m.vars.extra_tokens:
307 self._ever_ran_adb = True
308 # Remove ASAN.
309 self.m.run(self.m.step,
310 'wait for device before uninstalling ASAN',
311 cmd=[self.ADB_BINARY, 'wait-for-device', 'shell',
312 # Wait until the boot is actually complete.
313 # https://android.stackexchange.com/a/164050
314 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done',
315 ], infra_step=True,
316 timeout=180, abort_on_failure=False,
317 fail_build_on_failure=False)
318 self.m.run(self.m.step, 'uninstall ASAN',
319 cmd=[self._asan_setup_path(), '--revert'],
320 infra_step=True, timeout=300,
321 abort_on_failure=False, fail_build_on_failure=False)
322
323 if self._ever_ran_adb:
324 script = self.module.resource('dump_adb_log.py')
325 self.m.run(self.m.step, 'dump log',
326 cmd=['python3', script, self.host_dirs.bin_dir, self.ADB_BINARY],
327 infra_step=True,
328 timeout=300,
329 abort_on_failure=False)
330
331 # Only quarantine the bot if the first failed step
332 # is an infra step. If, instead, we did this for any infra failures, we
333 # would do this too much. For example, if a Nexus 10 died during dm
334 # and the following pull step would also fail "device not found" - causing
335 # us to run the shutdown command when the device was probably not in a
336 # broken state; it was just rebooting.
337 if (self.m.run.failed_steps and
338 isinstance(self.m.run.failed_steps[0], recipe_api.InfraFailure)):
339 bot_id = self.m.vars.swarming_bot_id
340 self.m.file.write_text('Quarantining Bot',
341 '/home/chrome-bot/%s.force_quarantine' % bot_id,
342 ' ')
343
344 # if self._ever_ran_adb:
345 # self._adb('kill adb server', 'kill-server')
346
static SkString resource(SkPDFResourceType type, int index)
Definition: run.py:1

◆ copy_directory_contents_to_device()

def flavor.android.AndroidFlavor.copy_directory_contents_to_device (   self,
  host_dir,
  device_dir 
)
Like shutil.copytree(), but for copying to a connected device.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 365 of file android.py.

365 def copy_directory_contents_to_device(self, host, device):
366 contents = self.m.file.glob_paths('ls %s/*' % host,
367 host, '*',
368 test_data=['foo.png', 'bar.jpg'])
369 args = contents + [device]
370 self._adb('push %s/* %s' % (host, device), 'push', *args)
371

◆ copy_directory_contents_to_host()

def flavor.android.AndroidFlavor.copy_directory_contents_to_host (   self,
  device_dir,
  host_dir 
)
Like shutil.copytree(), but for copying from a connected device.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 372 of file android.py.

372 def copy_directory_contents_to_host(self, device, host):
373 # TODO(borenet): When all of our devices are on Android 6.0 and up, we can
374 # switch to using tar to zip up the results before pulling.
375 with self.m.step.nest('adb pull'):
376 tmp = self.m.path.mkdtemp('adb_pull')
377 self._adb('pull %s' % device, 'pull', device, tmp)
378 paths = self.m.file.glob_paths(
379 'list pulled files',
380 tmp,
381 self.m.path.basename(device) + self.m.path.sep + '*',
382 test_data=['%d.png' % i for i in (1, 2)])
383 for p in paths:
384 self.m.file.copy('copy %s' % self.m.path.basename(p), p, host)
385

◆ copy_file_to_device()

def flavor.android.AndroidFlavor.copy_file_to_device (   self,
  host_path,
  device_path 
)
Like shutil.copyfile, but for copying to a connected device.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 362 of file android.py.

362 def copy_file_to_device(self, host, device):
363 self._adb('push %s %s' % (host, device), 'push', host, device)
364

◆ create_clean_device_dir()

def flavor.android.AndroidFlavor.create_clean_device_dir (   self,
  path 
)
Like shutil.rmtree() + os.makedirs(), but on a connected device.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 408 of file android.py.

408 def create_clean_device_dir(self, path):
409 self.remove_file_on_device(path)
410 self._adb('mkdir %s' % path, 'shell', 'mkdir', '-p', path)

◆ install()

def flavor.android.AndroidFlavor.install (   self)
Run device-specific installation steps.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 260 of file android.py.

260 def install(self):
261 self._adb('mkdir ' + self.device_dirs.resource_dir,
262 'shell', 'mkdir', '-p', self.device_dirs.resource_dir)
263 if self.m.vars.builder_cfg.get('model') in ['GalaxyS20', 'GalaxyS9']:
264 # See skia:10184, should be moot once upgraded to Android 11?
265 self._adb('cp libGLES_mali.so to ' + self.device_dirs.bin_dir,
266 'shell', 'cp',
267 '/vendor/lib64/egl/libGLES_mali.so',
268 self.device_dirs.bin_dir + 'libvulkan.so')
269 if 'ASAN' in self.m.vars.extra_tokens:
270 self._ever_ran_adb = True
271 script = self.module.resource('setup_device_for_asan.py')
272 self.m.run(
273 self.m.step, 'Setting up device to run ASAN',
274 cmd=['python3', script, self.ADB_BINARY, self._asan_setup_path()],
275 infra_step=True,
276 timeout=300,
277 abort_on_failure=True)
278 if self.app_name:
279 if (self.app_name == 'nanobench'):
280 self._scale_for_nanobench()
281 else:
282 self._scale_for_dm()
283 app_path = self.host_dirs.bin_dir.join(self.app_name)
284 self._adb('push %s' % self.app_name,
285 'push', app_path, self.device_dirs.bin_dir)
286
287
288
static bool install(SkBitmap *bm, const SkImageInfo &info, const SkRasterHandleAllocator::Rec &rec)
Definition: SkCanvas.cpp:2856

◆ read_file_on_device()

def flavor.android.AndroidFlavor.read_file_on_device (   self,
  path,
**  kwargs 
)
Reads the specified file.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 386 of file android.py.

386 def read_file_on_device(self, path, **kwargs):
387 testKwargs = {
388 'attempts': 1,
389 'abort_on_failure': False,
390 'fail_build_on_failure': False,
391 }
392 rv = self._adb('check if %s exists' % path,
393 'shell', 'test', '-f', path, **testKwargs)
394 if not rv: # pragma: nocover
395 return None
396
397 rv = self._adb('read %s' % path,
398 'shell', 'cat', path, stdout=self.m.raw_io.output(),
399 **kwargs)
400 return rv.stdout.decode('utf-8').rstrip() if rv and rv.stdout else None
401

◆ remove_file_on_device()

def flavor.android.AndroidFlavor.remove_file_on_device (   self,
  path 
)
Removes the specified file.

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 402 of file android.py.

402 def remove_file_on_device(self, path):
403 script = self.module.resource('remove_file_on_device.py')
404 self.m.run.with_retry(self.m.step, 'rm %s' % path, 3,
405 cmd=['python3', script, self.ADB_BINARY, path],
406 infra_step=True)
407

◆ step()

def flavor.android.AndroidFlavor.step (   self,
  name,
  cmd 
)

Reimplemented from flavor.default.DefaultFlavor.

Definition at line 347 of file android.py.

347 def step(self, name, cmd):
348 sh = '%s.sh' % cmd[0]
349 self.m.run.writefile(self.m.vars.tmp_dir.join(sh),
350 'set -x; LD_LIBRARY_PATH=%s %s%s; echo $? >%src' % (
351 self.device_dirs.bin_dir,
352 self.device_dirs.bin_dir, subprocess.list2cmdline(map(str, cmd)),
353 self.device_dirs.bin_dir))
354 self._adb('push %s' % sh,
355 'push', self.m.vars.tmp_dir.join(sh), self.device_dirs.bin_dir)
356
357 self._adb('clear log', 'logcat', '-c')
358 script = self.module.resource('run_sh.py')
359 self.m.step('%s' % cmd[0],
360 cmd=['python3', script, self.device_dirs.bin_dir, sh, self.ADB_BINARY])
361
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680

Member Data Documentation

◆ ADB_BINARY

flavor.android.AndroidFlavor.ADB_BINARY

Definition at line 20 of file android.py.

◆ ADB_PUB_KEY

flavor.android.AndroidFlavor.ADB_PUB_KEY

Definition at line 21 of file android.py.

◆ app_name

flavor.android.AndroidFlavor.app_name

Definition at line 279 of file android.py.

◆ cant_root

flavor.android.AndroidFlavor.cant_root

Definition at line 44 of file android.py.

◆ cpus_to_scale

flavor.android.AndroidFlavor.cpus_to_scale

Definition at line 57 of file android.py.

◆ device_dirs

flavor.android.AndroidFlavor.device_dirs

Definition at line 29 of file android.py.

◆ disable_for_nanobench

flavor.android.AndroidFlavor.disable_for_nanobench

Definition at line 69 of file android.py.

◆ gpu_scaling

flavor.android.AndroidFlavor.gpu_scaling

Definition at line 77 of file android.py.


The documentation for this class was generated from the following file: