| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2013 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 """ Utilities for Android build steps. """ | |
| 6 | |
| 7 from default_build_step_utils import DefaultBuildStepUtils, DeviceDirs | |
| 8 from py.utils import android_utils | |
| 9 from utils import old_gs_utils as gs_utils | |
| 10 from py.utils import shell_utils | |
| 11 | |
| 12 import os | |
| 13 import posixpath | |
| 14 import time | |
| 15 | |
| 16 | |
| 17 class AndroidBuildStepUtils(DefaultBuildStepUtils): | |
| 18 def __init__(self, build_step_instance): | |
| 19 DefaultBuildStepUtils.__init__(self, build_step_instance) | |
| 20 self._device = self._step.args['device'] | |
| 21 self._serial = self._step.args['serial'] if \ | |
| 22 self._step.args['serial'] != 'None' else None | |
| 23 self._has_root = self._step.args['has_root'] == 'True' | |
| 24 | |
| 25 def RunFlavoredCmd(self, app, args): | |
| 26 """ Override this in new BuildStep flavors. """ | |
| 27 # First, kill any running Skia executables. | |
| 28 android_utils.ADBKill(self._serial, 'skia') | |
| 29 release_mode = self._step.configuration == 'Release' | |
| 30 try: | |
| 31 android_utils.RunSkia(serial=self._serial, | |
| 32 cmd=[app] + args, | |
| 33 release=release_mode, | |
| 34 device=self._device) | |
| 35 finally: | |
| 36 # Make sure that no Skia process is hanging around after we're done. | |
| 37 android_utils.ADBKill(self._serial, 'skia') | |
| 38 | |
| 39 def ReadFileOnDevice(self, filepath): | |
| 40 """ Read the contents of a file on the device. """ | |
| 41 return android_utils.ADBShell(self._serial, ['cat', filepath, ';', 'echo'], | |
| 42 echo=False) | |
| 43 | |
| 44 def _RemoveDirectoryOnDevice(self, directory): | |
| 45 """ Delete a directory on the device. """ | |
| 46 try: | |
| 47 android_utils.RunADB(self._serial, ['shell', 'rm', '-r', directory]) | |
| 48 except Exception: | |
| 49 pass | |
| 50 if self.DevicePathExists(directory): | |
| 51 raise Exception('Failed to remove %s' % directory) | |
| 52 | |
| 53 def _CreateDirectoryOnDevice(self, directory): | |
| 54 """ Create a directory on the device. """ | |
| 55 android_utils.RunADB(self._serial, ['shell', 'mkdir', '-p', directory]) | |
| 56 | |
| 57 def PushFileToDevice(self, src, dst): | |
| 58 """ Overrides build_step.PushFileToDevice() """ | |
| 59 android_utils.RunADB(self._serial, ['push', src, dst]) | |
| 60 | |
| 61 def DeviceListDir(self, directory): | |
| 62 """ Overrides build_step.DeviceListDir() """ | |
| 63 return android_utils.ADBShell(self._serial, ['ls', directory], | |
| 64 echo=False).split('\n') | |
| 65 | |
| 66 def DevicePathExists(self, path): | |
| 67 """ Overrides build_step.DevicePathExists() """ | |
| 68 return 'FILE_EXISTS' in android_utils.ADBShell( | |
| 69 self._serial, | |
| 70 ['if', '[', '-e', path, '];', 'then', 'echo', 'FILE_EXISTS;', 'fi']) | |
| 71 | |
| 72 def DevicePathJoin(self, *args): | |
| 73 """ Overrides build_step.DevicePathJoin() """ | |
| 74 return posixpath.sep.join(args) | |
| 75 | |
| 76 def CreateCleanDeviceDirectory(self, directory): | |
| 77 self._RemoveDirectoryOnDevice(directory) | |
| 78 self._CreateDirectoryOnDevice(directory) | |
| 79 | |
| 80 def CopyDirectoryContentsToDevice(self, host_dir, device_dir): | |
| 81 """ Copy the contents of a host-side directory to a clean directory on the | |
| 82 device side. | |
| 83 """ | |
| 84 self.CreateCleanDeviceDirectory(device_dir) | |
| 85 file_list = os.listdir(host_dir) | |
| 86 for f in file_list: | |
| 87 if f == gs_utils.TIMESTAMP_COMPLETED_FILENAME: | |
| 88 continue | |
| 89 if os.path.isfile(os.path.join(host_dir, f)): | |
| 90 self.PushFileToDevice(os.path.join(host_dir, f), device_dir) | |
| 91 ts_filepath = os.path.join(host_dir, gs_utils.TIMESTAMP_COMPLETED_FILENAME) | |
| 92 if os.path.isfile(ts_filepath): | |
| 93 self.PushFileToDevice(ts_filepath, device_dir) | |
| 94 | |
| 95 def CopyDirectoryContentsToHost(self, device_dir, host_dir): | |
| 96 """ Copy the contents of a device-side directory to a clean directory on the | |
| 97 host side. | |
| 98 """ | |
| 99 self.CreateCleanHostDirectory(host_dir) | |
| 100 android_utils.RunADB(self._serial, ['pull', device_dir, host_dir]) | |
| 101 | |
| 102 def Install(self): | |
| 103 """ Install the Skia executables. """ | |
| 104 if self._has_root: | |
| 105 android_utils.RunADB(self._serial, ['root']) | |
| 106 android_utils.RunADB(self._serial, ['remount']) | |
| 107 # As an experiment, don't change CPU scaling mode. | |
| 108 #android_utils.SetCPUScalingMode(self._serial, 'performance') | |
| 109 try: | |
| 110 android_utils.ADBKill(self._serial, 'skia') | |
| 111 except Exception: | |
| 112 # If we fail to kill the process, try rebooting the device, and wait for | |
| 113 # it to come back up. | |
| 114 shell_utils.run([android_utils.PATH_TO_ADB, '-s', self._serial, | |
| 115 'reboot']) | |
| 116 time.sleep(60) | |
| 117 android_utils.StopShell(self._serial) | |
| 118 else: | |
| 119 android_utils.ADBKill(self._serial, 'com.skia', kill_app=True) | |
| 120 | |
| 121 def RunGYP(self): | |
| 122 print 'android_ninja handles gyp' | |
| 123 | |
| 124 def Compile(self, target): | |
| 125 """ Compile the Skia executables. """ | |
| 126 os.environ['SKIA_ANDROID_VERBOSE_SETUP'] = '1' | |
| 127 os.environ['PATH'] = os.path.abspath( | |
| 128 os.path.join(os.pardir, os.pardir, os.pardir, os.pardir, 'third_party', | |
| 129 'gsutil')) + os.pathsep + os.environ['PATH'] | |
| 130 os.environ['BOTO_CONFIG'] = os.path.abspath(os.path.join( | |
| 131 os.pardir, os.pardir, os.pardir, os.pardir, 'site_config', '.boto')) | |
| 132 os.environ['ANDROID_SDK_ROOT'] = self._step.args['android_sdk_root'] | |
| 133 gyp_defines = self._step.args['gyp_defines'] | |
| 134 os.environ['GYP_DEFINES'] = gyp_defines | |
| 135 print 'GYP_DEFINES="%s"' % os.environ['GYP_DEFINES'] | |
| 136 os.environ['BUILDTYPE'] = self._step.configuration | |
| 137 print 'BUILDTYPE="%s"' % os.environ['BUILDTYPE'] | |
| 138 cmd = [os.path.join('platform_tools', 'android', 'bin', 'android_ninja'), | |
| 139 target, | |
| 140 '-d', self._step.args['device'], | |
| 141 ] | |
| 142 cmd.extend(self._step.default_ninja_flags) | |
| 143 if os.name != 'nt': | |
| 144 try: | |
| 145 ccache = shell_utils.run(['which', 'ccache']).rstrip() | |
| 146 if ccache: | |
| 147 os.environ['ANDROID_MAKE_CCACHE'] = ccache | |
| 148 except Exception: | |
| 149 pass | |
| 150 cmd.extend(self._step.make_flags) | |
| 151 shell_utils.run(cmd) | |
| 152 | |
| 153 def PreRun(self): | |
| 154 """ Preprocessing step to run before the BuildStep itself. """ | |
| 155 os.environ['ANDROID_SDK_ROOT'] = self._step.args['android_sdk_root'] | |
| 156 | |
| 157 def GetDeviceDirs(self): | |
| 158 """ Set the directories which will be used by the BuildStep. """ | |
| 159 if self._serial: | |
| 160 device_scratch_dir = shell_utils.run( | |
| 161 '%s -s %s shell echo \$EXTERNAL_STORAGE' % ( | |
| 162 android_utils.PATH_TO_ADB, self._serial), | |
| 163 echo=True, shell=True).rstrip().split('\n')[-1] | |
| 164 prefix = posixpath.join(device_scratch_dir, 'skiabot', 'skia_') | |
| 165 return DeviceDirs( | |
| 166 perf_data_dir=prefix + 'perf', | |
| 167 gm_actual_dir=prefix + 'gm_actual', | |
| 168 gm_expected_dir=prefix + 'gm_expected', | |
| 169 dm_dir=prefix + 'dm', | |
| 170 resource_dir=prefix + 'resources', | |
| 171 skimage_in_dir=prefix + 'skimage_in', | |
| 172 skimage_expected_dir=prefix + 'skimage_expected', | |
| 173 skimage_out_dir=prefix + 'skimage_out', | |
| 174 skp_dir=prefix + 'skp', | |
| 175 skp_perf_dir=prefix + 'skp_perf', | |
| 176 playback_actual_images_dir=prefix + 'playback_actual_images', | |
| 177 playback_actual_summaries_dir=prefix + 'playback_actual_summaries', | |
| 178 playback_expected_summaries_dir=( | |
| 179 prefix + 'playback_expected_summaries'), | |
| 180 tmp_dir=prefix + 'tmp_dir') | |
| OLD | NEW |