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 |