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 stdout=subprocess.PIPE, |
203 stderr=subprocess.STDOUT) | 209 stderr=subprocess.STDOUT) |
204 avd_process.stdin.write('no\n') | 210 avd_process.stdin.write('no\n') |
205 avd_process.wait() | 211 avd_process.wait() |
frankf
2013/04/05 21:05:48
This can cause a deadlock. Don't call subprocess d
navabi
2013/04/08 21:41:56
I can change the others, but in this case, we have
Isaac (away)
2013/04/08 21:45:52
I'm not sure this can cause deadlock, but what abo
navabi
2013/04/08 22:04:51
Done.
cjhopman
2013/04/09 00:17:26
Search for "deadlock" at http://docs.python.org/2/
| |
212 | |
206 logging.info('Create AVD command: %s', ' '.join(avd_command)) | 213 logging.info('Create AVD command: %s', ' '.join(avd_command)) |
214 | |
215 # Setup test device as default Galaxy Nexus AVD | |
216 avd_config_dir = os.path.join(constants.CHROME_DIR, 'build', 'android', | |
217 'avd_configs') | |
218 avd_ini = os.path.join(avd_config_dir, | |
219 'AVD_for_Galaxy_Nexus_by_Google_%s.ini' % | |
pasko-google - do not use
2013/04/05 09:41:05
spacing nit:
align under the previous argument
navabi
2013/04/08 21:41:56
Done.
| |
220 self.abi) | |
221 avd_config_ini = os.path.join(avd_config_dir, | |
222 'AVD_for_Galaxy_Nexus_by_Google_%s.avd' % | |
223 self.abi, 'config.ini') | |
224 | |
225 # Replace current configuration with default Galaxy Nexus config. | |
226 avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd') | |
227 new_ini = os.path.join(avds_dir, '%s.ini' % self.avd_name) | |
228 new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name, | |
229 'config.ini') | |
230 | |
231 os.unlink(new_ini) | |
232 os.unlink(new_config_ini) | |
233 shutil.copy(avd_ini, new_ini) | |
234 shutil.copy(avd_config_ini, new_config_ini) | |
235 | |
236 replace_sed = 's/AVD_for_Galaxy_Nexus_by_Google_%s/%s/g' % (self.abi, | |
237 self.avd_name) | |
238 replace_name = subprocess.Popen(['sed', '-i', replace_sed, new_ini]) | |
pasko-google - do not use
2013/04/05 09:41:05
Instead of copying, replacing with sed via subproc
nyquist
2013/04/05 20:49:35
And if line-wrapping, etc. becomes ugly, consider
navabi
2013/04/08 21:41:56
Done.
| |
239 replace_name.wait() | |
240 | |
207 return self.avd_name | 241 return self.avd_name |
208 | 242 |
209 def _DeleteAVD(self): | 243 def _DeleteAVD(self): |
210 """Delete the AVD of this emulator.""" | 244 """Delete the AVD of this emulator.""" |
211 avd_command = [ | 245 avd_command = [ |
212 self.android, | 246 self.android, |
213 '--silent', | 247 '--silent', |
214 'delete', | 248 'delete', |
215 'avd', | 249 'avd', |
216 '--name', self.avd, | 250 '--name', self.avd, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 logging.critical('emulator _ShutdownOnSignal') | 360 logging.critical('emulator _ShutdownOnSignal') |
327 for sig in self._SIGNALS: | 361 for sig in self._SIGNALS: |
328 signal.signal(sig, signal.SIG_DFL) | 362 signal.signal(sig, signal.SIG_DFL) |
329 self.Shutdown() | 363 self.Shutdown() |
330 raise KeyboardInterrupt # print a stack | 364 raise KeyboardInterrupt # print a stack |
331 | 365 |
332 def _InstallKillHandler(self): | 366 def _InstallKillHandler(self): |
333 """Install a handler to kill the emulator when we exit unexpectedly.""" | 367 """Install a handler to kill the emulator when we exit unexpectedly.""" |
334 for sig in self._SIGNALS: | 368 for sig in self._SIGNALS: |
335 signal.signal(sig, self._ShutdownOnSignal) | 369 signal.signal(sig, self._ShutdownOnSignal) |
OLD | NEW |