Chromium Code Reviews| 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 |