OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Provides an interface to start and stop Android emulator. | 7 """Provides an interface to start and stop Android emulator. |
8 | 8 |
9 Assumes system environment ANDROID_NDK_ROOT has been set. | 9 Assumes system environment ANDROID_NDK_ROOT has been set. |
10 | 10 |
11 Emulator: The class provides the methods to launch/shutdown the emulator with | 11 Emulator: The class provides the methods to launch/shutdown the emulator with |
12 the android virtual device named 'avd_armeabi' . | 12 the android virtual device named 'avd_armeabi' . |
13 """ | 13 """ |
14 | 14 |
15 import logging | 15 import logging |
16 import os | 16 import os |
17 import shutil | |
17 import signal | 18 import signal |
18 import subprocess | 19 import subprocess |
19 import sys | 20 import sys |
20 import time | 21 import time |
21 | 22 |
22 import time_profile | 23 import time_profile |
23 # TODO(craigdh): Move these pylib dependencies to pylib/utils/. | 24 # TODO(craigdh): Move these pylib dependencies to pylib/utils/. |
24 from pylib import android_commands | 25 from pylib import android_commands |
25 from pylib import cmd_helper | 26 from pylib import cmd_helper |
26 from pylib import constants | 27 from pylib import constants |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 # the time to launch the emulator and a wait-for-device command. | 154 # the time to launch the emulator and a wait-for-device command. |
154 _LAUNCH_TIMEOUT = 120 | 155 _LAUNCH_TIMEOUT = 120 |
155 | 156 |
156 # Timeout interval of wait-for-device command before bouncing to a a | 157 # Timeout interval of wait-for-device command before bouncing to a a |
157 # process life check. | 158 # process life check. |
158 _WAITFORDEVICE_TIMEOUT = 5 | 159 _WAITFORDEVICE_TIMEOUT = 5 |
159 | 160 |
160 # Time to wait for a "wait for boot complete" (property set on device). | 161 # Time to wait for a "wait for boot complete" (property set on device). |
161 _WAITFORBOOT_TIMEOUT = 300 | 162 _WAITFORBOOT_TIMEOUT = 300 |
162 | 163 |
163 def __init__(self, avd_name, abi='x86'): | 164 def __init__(self, avd_name, abi): |
164 """Init an Emulator. | 165 """Init an Emulator. |
165 | 166 |
166 Args: | 167 Args: |
167 avd_name: name of the AVD to create | 168 avd_name: name of the AVD to create |
168 abi: target platform for emulator being created | 169 abi: target platform for emulator being created |
169 """ | 170 """ |
170 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, | 171 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, |
171 'android_tools', 'sdk') | 172 'android_tools', 'sdk') |
172 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator') | 173 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator') |
173 self.android = os.path.join(android_sdk_root, 'tools', 'android') | 174 self.android = os.path.join(android_sdk_root, 'tools', 'android') |
174 self.popen = None | 175 self.popen = None |
175 self.device = None | 176 self.device = None |
176 self.abi = abi | 177 self.abi = abi |
177 self.avd_name = avd_name | 178 self.avd_name = avd_name |
178 self._CreateAVD() | 179 self._CreateAVD() |
179 | 180 |
180 def _DeviceName(self): | 181 def _DeviceName(self): |
181 """Return our device name.""" | 182 """Return our device name.""" |
182 port = _GetAvailablePort() | 183 port = _GetAvailablePort() |
183 return ('emulator-%d' % port, port) | 184 return ('emulator-%d' % port, port) |
184 | 185 |
185 def _CreateAVD(self): | 186 def _CreateAVD(self): |
186 """Creates an AVD with the given name. | 187 """Creates an AVD with the given name. |
187 | 188 |
188 Return avd_name. | 189 Return avd_name. |
189 """ | 190 """ |
191 | |
192 if self.abi == 'arm': | |
193 abi_option = 'armeabi-v7a' | |
194 else: | |
195 abi_option = 'x86' | |
196 | |
190 avd_command = [ | 197 avd_command = [ |
191 self.android, | 198 self.android, |
192 '--silent', | 199 '--silent', |
193 'create', 'avd', | 200 'create', 'avd', |
194 '--name', self.avd_name, | 201 '--name', self.avd_name, |
195 '--abi', self.abi, | 202 '--abi', abi_option, |
196 '--target', API_TARGET, | 203 '--target', API_TARGET, |
197 '-c', '128M', | |
198 '--force', | 204 '--force', |
199 ] | 205 ] |
200 avd_process = subprocess.Popen(args=avd_command, | 206 avd_process = subprocess.Popen(args=avd_command, |
201 stdin=subprocess.PIPE, | 207 stdin=subprocess.PIPE) |
202 stdout=subprocess.PIPE, | 208 avd_process.communicate('no\n') |
203 stderr=subprocess.STDOUT) | 209 |
204 avd_process.stdin.write('no\n') | |
205 avd_process.wait() | |
206 logging.info('Create AVD command: %s', ' '.join(avd_command)) | 210 logging.info('Create AVD command: %s', ' '.join(avd_command)) |
211 | |
212 # Setup test device as default Galaxy Nexus AVD | |
213 avd_config_dir = os.path.join(constants.CHROME_DIR, 'build', 'android', | |
214 'avd_configs') | |
215 avd_config_ini = os.path.join(avd_config_dir, | |
216 'AVD_for_Galaxy_Nexus_by_Google_%s.avd' % | |
217 self.abi, 'config.ini') | |
218 | |
219 # Replace current configuration with default Galaxy Nexus config. | |
220 avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd') | |
221 ini_file = os.path.join(avds_dir, '%s.ini' % self.avd_name) | |
222 new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name, | |
223 'config.ini') | |
224 | |
225 # Remove non-standard configuration files | |
pasko-google - do not use
2013/04/09 08:41:45
Why are they non-standard? We rather cleanup befor
navabi
2013/04/09 16:46:51
"non-standard" is not the correct phrasing. The co
| |
226 os.unlink(ini_file) | |
227 os.unlink(new_config_ini) | |
228 | |
229 # Create new configuration files with Galaxy Nexus by Google settings. | |
230 with open(ini_file, 'w') as new_ini: | |
231 new_ini.write('avd.ini.encoding=ISO-8859-1\n') | |
232 new_ini.write('target=%s\n' % API_TARGET) | |
233 new_ini.write('path=%s/%s.avd\n' % (avds_dir, self.avd_name)) | |
234 new_ini.write('path.rel=avd/%s.avd\n' % self.avd_name) | |
235 | |
236 shutil.copy(avd_config_ini, new_config_ini) | |
207 return self.avd_name | 237 return self.avd_name |
208 | 238 |
239 | |
209 def _DeleteAVD(self): | 240 def _DeleteAVD(self): |
210 """Delete the AVD of this emulator.""" | 241 """Delete the AVD of this emulator.""" |
211 avd_command = [ | 242 avd_command = [ |
212 self.android, | 243 self.android, |
213 '--silent', | 244 '--silent', |
214 'delete', | 245 'delete', |
215 'avd', | 246 'avd', |
216 '--name', self.avd, | 247 '--name', self.avd_name, |
217 ] | 248 ] |
218 avd_process = subprocess.Popen(args=avd_command, | |
219 stdout=subprocess.PIPE, | |
220 stderr=subprocess.STDOUT) | |
221 logging.info('Delete AVD command: %s', ' '.join(avd_command)) | 249 logging.info('Delete AVD command: %s', ' '.join(avd_command)) |
222 avd_process.wait() | 250 cmd_helper.GetCmdOutput(avd_command) |
251 | |
223 | 252 |
224 def Launch(self, kill_all_emulators): | 253 def Launch(self, kill_all_emulators): |
225 """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the | 254 """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the |
226 emulator is ready for use. | 255 emulator is ready for use. |
227 | 256 |
228 If fails, an exception will be raised. | 257 If fails, an exception will be raised. |
229 """ | 258 """ |
230 if kill_all_emulators: | 259 if kill_all_emulators: |
231 _KillAllEmulators() # just to be sure | 260 _KillAllEmulators() # just to be sure |
232 self._AggressiveImageCleanup() | 261 self._AggressiveImageCleanup() |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 logging.critical('emulator _ShutdownOnSignal') | 355 logging.critical('emulator _ShutdownOnSignal') |
327 for sig in self._SIGNALS: | 356 for sig in self._SIGNALS: |
328 signal.signal(sig, signal.SIG_DFL) | 357 signal.signal(sig, signal.SIG_DFL) |
329 self.Shutdown() | 358 self.Shutdown() |
330 raise KeyboardInterrupt # print a stack | 359 raise KeyboardInterrupt # print a stack |
331 | 360 |
332 def _InstallKillHandler(self): | 361 def _InstallKillHandler(self): |
333 """Install a handler to kill the emulator when we exit unexpectedly.""" | 362 """Install a handler to kill the emulator when we exit unexpectedly.""" |
334 for sig in self._SIGNALS: | 363 for sig in self._SIGNALS: |
335 signal.signal(sig, self._ShutdownOnSignal) | 364 signal.signal(sig, self._ShutdownOnSignal) |
OLD | NEW |