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

Side by Side Diff: build/android/pylib/utils/emulator.py

Issue 72383005: Emulator script improvements: config templates, --api-level, and mips support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 7 years, 1 month 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 | « build/android/avd_configs/AVD_for_Galaxy_Nexus_by_Google_x86.avd/config.ini ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Provides an interface to start and stop Android emulator. 5 """Provides an interface to start and stop Android emulator.
6 6
7 Assumes system environment ANDROID_NDK_ROOT has been set. 7 Assumes system environment ANDROID_NDK_ROOT has been set.
8 8
9 Emulator: The class provides the methods to launch/shutdown the emulator with 9 Emulator: The class provides the methods to launch/shutdown the emulator with
10 the android virtual device named 'avd_armeabi' . 10 the android virtual device named 'avd_armeabi' .
(...skipping 10 matching lines...) Expand all
21 import time_profile 21 import time_profile
22 # TODO(craigdh): Move these pylib dependencies to pylib/utils/. 22 # TODO(craigdh): Move these pylib dependencies to pylib/utils/.
23 from pylib import android_commands 23 from pylib import android_commands
24 from pylib import cmd_helper 24 from pylib import cmd_helper
25 from pylib import constants 25 from pylib import constants
26 from pylib import pexpect 26 from pylib import pexpect
27 27
28 import errors 28 import errors
29 import run_command 29 import run_command
30 30
31 # Android API level
32 API_TARGET = 'android-%s' % constants.ANDROID_SDK_VERSION
33
34 # SD card size 31 # SD card size
35 SDCARD_SIZE = '512M' 32 SDCARD_SIZE = '512M'
36 33
34 # Template used to generate config.ini files for the emulator
35 CONFIG_TEMPLATE = """avd.ini.encoding=ISO-8859-1
36 hw.dPad=no
37 hw.lcd.density=320
38 sdcard.size=512M
39 hw.cpu.arch={hw.cpu.arch}
40 hw.device.hash=-708107041
41 hw.camera.back=none
42 disk.dataPartition.size=800M
43 hw.gpu.enabled=yes
44 skin.path=720x1280
45 skin.dynamic=yes
46 hw.keyboard=yes
47 hw.ramSize=1024
48 hw.device.manufacturer=Google
49 hw.sdCard=yes
50 hw.mainKeys=no
51 hw.accelerometer=yes
52 skin.name=720x1280
53 abi.type={abi.type}
54 hw.trackBall=no
55 hw.device.name=Galaxy Nexus
56 hw.battery=yes
57 hw.sensors.proximity=yes
58 image.sysdir.1=system-images/android-{api.level}/{abi.type}/
59 hw.sensors.orientation=yes
60 hw.audioInput=yes
61 hw.camera.front=none
62 hw.gps=yes
63 vm.heapSize=128
64 {extras}"""
65
66 CONFIG_REPLACEMENTS = {
67 'x86': {
68 '{hw.cpu.arch}': 'x86',
69 '{abi.type}': 'x86',
70 '{extras}': ''
71 },
72 'arm': {
73 '{hw.cpu.arch}': 'arm',
74 '{abi.type}': 'armeabi-v7a',
75 '{extras}': 'hw.cpu.model=cortex-a8\n'
76 },
77 'mips': {
78 '{hw.cpu.arch}': 'mips',
79 '{abi.type}': 'mips',
80 '{extras}': ''
81 }
82 }
83
37 class EmulatorLaunchException(Exception): 84 class EmulatorLaunchException(Exception):
38 """Emulator failed to launch.""" 85 """Emulator failed to launch."""
39 pass 86 pass
40 87
41 def _KillAllEmulators(): 88 def _KillAllEmulators():
42 """Kill all running emulators that look like ones we started. 89 """Kill all running emulators that look like ones we started.
43 90
44 There are odd 'sticky' cases where there can be no emulator process 91 There are odd 'sticky' cases where there can be no emulator process
45 running but a device slot is taken. A little bot trouble and and 92 running but a device slot is taken. A little bot trouble and and
46 we're out of room forever. 93 we're out of room forever.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 """Returns an available TCP port for the console.""" 144 """Returns an available TCP port for the console."""
98 used_ports = [] 145 used_ports = []
99 emulators = android_commands.GetAttachedDevices(hardware=False) 146 emulators = android_commands.GetAttachedDevices(hardware=False)
100 for emulator in emulators: 147 for emulator in emulators:
101 used_ports.append(emulator.split('-')[1]) 148 used_ports.append(emulator.split('-')[1])
102 for port in PortPool.port_range(): 149 for port in PortPool.port_range():
103 if str(port) not in used_ports: 150 if str(port) not in used_ports:
104 return port 151 return port
105 152
106 153
107 def LaunchEmulators(emulator_count, abi, wait_for_boot=True): 154 def LaunchEmulators(emulator_count, abi, api_level, wait_for_boot=True):
108 """Launch multiple emulators and wait for them to boot. 155 """Launch multiple emulators and wait for them to boot.
109 156
110 Args: 157 Args:
111 emulator_count: number of emulators to launch. 158 emulator_count: number of emulators to launch.
112 abi: the emulator target platform 159 abi: the emulator target platform
160 api_level: the api level (e.g., 19 for Android v4.4 - KitKat release)
113 wait_for_boot: whether or not to wait for emulators to boot up 161 wait_for_boot: whether or not to wait for emulators to boot up
114 162
115 Returns: 163 Returns:
116 List of emulators. 164 List of emulators.
117 """ 165 """
118 emulators = [] 166 emulators = []
119 for n in xrange(emulator_count): 167 for n in xrange(emulator_count):
120 t = time_profile.TimeProfile('Emulator launch %d' % n) 168 t = time_profile.TimeProfile('Emulator launch %d' % n)
121 # Creates a temporary AVD. 169 # Creates a temporary AVD.
122 avd_name = 'run_tests_avd_%d' % n 170 avd_name = 'run_tests_avd_%d' % n
123 logging.info('Emulator launch %d with avd_name=%s', n, avd_name) 171 logging.info('Emulator launch %d with avd_name=%s and api=%d',
124 emulator = Emulator(avd_name, abi) 172 n, avd_name, api_level)
173 emulator = Emulator(avd_name, abi, api_level)
125 emulator.Launch(kill_all_emulators=n == 0) 174 emulator.Launch(kill_all_emulators=n == 0)
126 t.Stop() 175 t.Stop()
127 emulators.append(emulator) 176 emulators.append(emulator)
128 # Wait for all emulators to boot completed. 177 # Wait for all emulators to boot completed.
129 if wait_for_boot: 178 if wait_for_boot:
130 for emulator in emulators: 179 for emulator in emulators:
131 emulator.ConfirmLaunch(True) 180 emulator.ConfirmLaunch(True)
132 return emulators 181 return emulators
133 182
134 183
(...skipping 20 matching lines...) Expand all
155 # the time to launch the emulator and a wait-for-device command. 204 # the time to launch the emulator and a wait-for-device command.
156 _LAUNCH_TIMEOUT = 120 205 _LAUNCH_TIMEOUT = 120
157 206
158 # Timeout interval of wait-for-device command before bouncing to a a 207 # Timeout interval of wait-for-device command before bouncing to a a
159 # process life check. 208 # process life check.
160 _WAITFORDEVICE_TIMEOUT = 5 209 _WAITFORDEVICE_TIMEOUT = 5
161 210
162 # Time to wait for a "wait for boot complete" (property set on device). 211 # Time to wait for a "wait for boot complete" (property set on device).
163 _WAITFORBOOT_TIMEOUT = 300 212 _WAITFORBOOT_TIMEOUT = 300
164 213
165 def __init__(self, avd_name, abi): 214 def __init__(self, avd_name, abi, api_level):
166 """Init an Emulator. 215 """Init an Emulator.
167 216
168 Args: 217 Args:
169 avd_name: name of the AVD to create 218 avd_name: name of the AVD to create
170 abi: target platform for emulator being created 219 abi: target platform for emulator being created, defaults to x86
220 api_level: the api level of the image
171 """ 221 """
172 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk') 222 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk')
173 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator') 223 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator')
174 self.android = os.path.join(android_sdk_root, 'tools', 'android') 224 self.android = os.path.join(android_sdk_root, 'tools', 'android')
175 self.popen = None 225 self.popen = None
176 self.device = None 226 self.device = None
177 self.abi = abi 227 self.abi = abi
178 self.avd_name = avd_name 228 self.avd_name = avd_name
229 self.api_level = api_level
179 self._CreateAVD() 230 self._CreateAVD()
180 231
181 def _DeviceName(self): 232 def _DeviceName(self):
182 """Return our device name.""" 233 """Return our device name."""
183 port = _GetAvailablePort() 234 port = _GetAvailablePort()
184 return ('emulator-%d' % port, port) 235 return ('emulator-%d' % port, port)
185 236
186 def _CreateAVD(self): 237 def _CreateAVD(self):
187 """Creates an AVD with the given name. 238 """Creates an AVD with the given name.
188 239
189 Return avd_name. 240 Return avd_name.
190 """ 241 """
191 242
192 if self.abi == 'arm': 243 if self.abi == 'arm':
193 abi_option = 'armeabi-v7a' 244 abi_option = 'armeabi-v7a'
245 elif self.abi == 'mips':
246 abi_option = 'mips'
194 else: 247 else:
195 abi_option = 'x86' 248 abi_option = 'x86'
196 249
250 api_target = 'android-%s' % self.api_level
251
197 avd_command = [ 252 avd_command = [
198 self.android, 253 self.android,
199 '--silent', 254 '--silent',
200 'create', 'avd', 255 'create', 'avd',
201 '--name', self.avd_name, 256 '--name', self.avd_name,
202 '--abi', abi_option, 257 '--abi', abi_option,
203 '--target', API_TARGET, 258 '--target', api_target,
204 '--sdcard', SDCARD_SIZE, 259 '--sdcard', SDCARD_SIZE,
205 '--force', 260 '--force',
206 ] 261 ]
207 avd_cmd_str = ' '.join(avd_command) 262 avd_cmd_str = ' '.join(avd_command)
208 logging.info('Create AVD command: %s', avd_cmd_str) 263 logging.info('Create AVD command: %s', avd_cmd_str)
209 avd_process = pexpect.spawn(avd_cmd_str) 264 avd_process = pexpect.spawn(avd_cmd_str)
210 265
211 # Instead of creating a custom profile, we overwrite config files. 266 # Instead of creating a custom profile, we overwrite config files.
212 avd_process.expect('Do you wish to create a custom hardware profile') 267 avd_process.expect('Do you wish to create a custom hardware profile')
213 avd_process.sendline('no\n') 268 avd_process.sendline('no\n')
214 avd_process.expect('Created AVD \'%s\'' % self.avd_name) 269 avd_process.expect('Created AVD \'%s\'' % self.avd_name)
215 270
216 # Setup test device as default Galaxy Nexus AVD
217 avd_config_dir = os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android',
218 'avd_configs')
219 avd_config_ini = os.path.join(avd_config_dir,
220 'AVD_for_Galaxy_Nexus_by_Google_%s.avd' %
221 self.abi, 'config.ini')
222
223 # Replace current configuration with default Galaxy Nexus config. 271 # Replace current configuration with default Galaxy Nexus config.
224 avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd') 272 avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd')
225 ini_file = os.path.join(avds_dir, '%s.ini' % self.avd_name) 273 ini_file = os.path.join(avds_dir, '%s.ini' % self.avd_name)
226 new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name, 274 new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name,
227 'config.ini') 275 'config.ini')
228 276
229 # Remove config files with defaults to replace with Google's GN settings. 277 # Remove config files with defaults to replace with Google's GN settings.
230 os.unlink(ini_file) 278 os.unlink(ini_file)
231 os.unlink(new_config_ini) 279 os.unlink(new_config_ini)
232 280
233 # Create new configuration files with Galaxy Nexus by Google settings. 281 # Create new configuration files with Galaxy Nexus by Google settings.
234 with open(ini_file, 'w') as new_ini: 282 with open(ini_file, 'w') as new_ini:
235 new_ini.write('avd.ini.encoding=ISO-8859-1\n') 283 new_ini.write('avd.ini.encoding=ISO-8859-1\n')
236 new_ini.write('target=%s\n' % API_TARGET) 284 new_ini.write('target=%s\n' % api_target)
237 new_ini.write('path=%s/%s.avd\n' % (avds_dir, self.avd_name)) 285 new_ini.write('path=%s/%s.avd\n' % (avds_dir, self.avd_name))
238 new_ini.write('path.rel=avd/%s.avd\n' % self.avd_name) 286 new_ini.write('path.rel=avd/%s.avd\n' % self.avd_name)
239 287
240 shutil.copy(avd_config_ini, new_config_ini) 288 custom_config = CONFIG_TEMPLATE
289 replacements = CONFIG_REPLACEMENTS[self.abi]
290 for key in replacements:
291 custom_config = custom_config.replace(key, replacements[key])
292 custom_config = custom_config.replace('{api.level}', str(self.api_level))
293
294 with open(new_config_ini, 'w') as new_config_ini:
295 new_config_ini.write(custom_config)
296
241 return self.avd_name 297 return self.avd_name
242 298
243 299
244 def _DeleteAVD(self): 300 def _DeleteAVD(self):
245 """Delete the AVD of this emulator.""" 301 """Delete the AVD of this emulator."""
246 avd_command = [ 302 avd_command = [
247 self.android, 303 self.android,
248 '--silent', 304 '--silent',
249 'delete', 305 'delete',
250 'avd', 306 'avd',
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 logging.critical('emulator _ShutdownOnSignal') 415 logging.critical('emulator _ShutdownOnSignal')
360 for sig in self._SIGNALS: 416 for sig in self._SIGNALS:
361 signal.signal(sig, signal.SIG_DFL) 417 signal.signal(sig, signal.SIG_DFL)
362 self.Shutdown() 418 self.Shutdown()
363 raise KeyboardInterrupt # print a stack 419 raise KeyboardInterrupt # print a stack
364 420
365 def _InstallKillHandler(self): 421 def _InstallKillHandler(self):
366 """Install a handler to kill the emulator when we exit unexpectedly.""" 422 """Install a handler to kill the emulator when we exit unexpectedly."""
367 for sig in self._SIGNALS: 423 for sig in self._SIGNALS:
368 signal.signal(sig, self._ShutdownOnSignal) 424 signal.signal(sig, self._ShutdownOnSignal)
OLDNEW
« no previous file with comments | « build/android/avd_configs/AVD_for_Galaxy_Nexus_by_Google_x86.avd/config.ini ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698