| OLD | NEW |
| 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' . |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import logging | 13 import logging |
| 14 import os | 14 import os |
| 15 import signal | 15 import signal |
| 16 import subprocess | 16 import subprocess |
| 17 import time | 17 import time |
| 18 | 18 |
| 19 # TODO(craigdh): Move these pylib dependencies to pylib/utils/. | 19 # TODO(craigdh): Move these pylib dependencies to pylib/utils/. |
| 20 from pylib import android_commands | 20 from pylib import android_commands |
| 21 from pylib import cmd_helper | 21 from pylib import cmd_helper |
| 22 from pylib import constants | 22 from pylib import constants |
| 23 from pylib import pexpect | 23 from pylib import pexpect |
| 24 from pylib.device import device_utils |
| 24 from pylib.utils import time_profile | 25 from pylib.utils import time_profile |
| 25 | 26 |
| 26 import errors | 27 import errors |
| 27 import run_command | 28 import run_command |
| 28 | 29 |
| 29 # SD card size | 30 # SD card size |
| 30 SDCARD_SIZE = '512M' | 31 SDCARD_SIZE = '512M' |
| 31 | 32 |
| 32 # Template used to generate config.ini files for the emulator | 33 # Template used to generate config.ini files for the emulator |
| 33 CONFIG_TEMPLATE = """avd.ini.encoding=ISO-8859-1 | 34 CONFIG_TEMPLATE = """avd.ini.encoding=ISO-8859-1 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 return | 102 return |
| 102 time.sleep(1) | 103 time.sleep(1) |
| 103 | 104 |
| 104 | 105 |
| 105 def DeleteAllTempAVDs(): | 106 def DeleteAllTempAVDs(): |
| 106 """Delete all temporary AVDs which are created for tests. | 107 """Delete all temporary AVDs which are created for tests. |
| 107 | 108 |
| 108 If the test exits abnormally and some temporary AVDs created when testing may | 109 If the test exits abnormally and some temporary AVDs created when testing may |
| 109 be left in the system. Clean these AVDs. | 110 be left in the system. Clean these AVDs. |
| 110 """ | 111 """ |
| 111 avds = android_commands.GetAVDs() | 112 avds = device_utils.GetAVDs() |
| 112 if not avds: | 113 if not avds: |
| 113 return | 114 return |
| 114 for avd_name in avds: | 115 for avd_name in avds: |
| 115 if 'run_tests_avd' in avd_name: | 116 if 'run_tests_avd' in avd_name: |
| 116 cmd = ['android', '-s', 'delete', 'avd', '--name', avd_name] | 117 cmd = ['android', '-s', 'delete', 'avd', '--name', avd_name] |
| 117 cmd_helper.RunCmd(cmd) | 118 cmd_helper.RunCmd(cmd) |
| 118 logging.info('Delete AVD %s' % avd_name) | 119 logging.info('Delete AVD %s' % avd_name) |
| 119 | 120 |
| 120 | 121 |
| 121 class PortPool(object): | 122 class PortPool(object): |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 """Init an Emulator. | 232 """Init an Emulator. |
| 232 | 233 |
| 233 Args: | 234 Args: |
| 234 avd_name: name of the AVD to create | 235 avd_name: name of the AVD to create |
| 235 abi: target platform for emulator being created, defaults to x86 | 236 abi: target platform for emulator being created, defaults to x86 |
| 236 """ | 237 """ |
| 237 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk') | 238 android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk') |
| 238 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator') | 239 self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator') |
| 239 self.android = os.path.join(android_sdk_root, 'tools', 'android') | 240 self.android = os.path.join(android_sdk_root, 'tools', 'android') |
| 240 self.popen = None | 241 self.popen = None |
| 241 self.device = None | 242 self.device_serial = None |
| 242 self.abi = abi | 243 self.abi = abi |
| 243 self.avd_name = avd_name | 244 self.avd_name = avd_name |
| 244 | 245 |
| 245 @staticmethod | 246 @staticmethod |
| 246 def _DeviceName(): | 247 def _DeviceName(): |
| 247 """Return our device name.""" | 248 """Return our device name.""" |
| 248 port = _GetAvailablePort() | 249 port = _GetAvailablePort() |
| 249 return ('emulator-%d' % port, port) | 250 return ('emulator-%d' % port, port) |
| 250 | 251 |
| 251 def CreateAVD(self, api_level): | 252 def CreateAVD(self, api_level): |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 | 330 |
| 330 def Launch(self, kill_all_emulators): | 331 def Launch(self, kill_all_emulators): |
| 331 """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the | 332 """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the |
| 332 emulator is ready for use. | 333 emulator is ready for use. |
| 333 | 334 |
| 334 If fails, an exception will be raised. | 335 If fails, an exception will be raised. |
| 335 """ | 336 """ |
| 336 if kill_all_emulators: | 337 if kill_all_emulators: |
| 337 _KillAllEmulators() # just to be sure | 338 _KillAllEmulators() # just to be sure |
| 338 self._AggressiveImageCleanup() | 339 self._AggressiveImageCleanup() |
| 339 (self.device, port) = self._DeviceName() | 340 (self.device_serial, port) = self._DeviceName() |
| 340 emulator_command = [ | 341 emulator_command = [ |
| 341 self.emulator, | 342 self.emulator, |
| 342 # Speed up emulator launch by 40%. Really. | 343 # Speed up emulator launch by 40%. Really. |
| 343 '-no-boot-anim', | 344 '-no-boot-anim', |
| 344 # The default /data size is 64M. | 345 # The default /data size is 64M. |
| 345 # That's not enough for 8 unit test bundles and their data. | 346 # That's not enough for 8 unit test bundles and their data. |
| 346 '-partition-size', '512', | 347 '-partition-size', '512', |
| 347 # Use a familiar name and port. | 348 # Use a familiar name and port. |
| 348 '-avd', self.avd_name, | 349 '-avd', self.avd_name, |
| 349 '-port', str(port), | 350 '-port', str(port), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 def ConfirmLaunch(self, wait_for_boot=False): | 389 def ConfirmLaunch(self, wait_for_boot=False): |
| 389 """Confirm the emulator launched properly. | 390 """Confirm the emulator launched properly. |
| 390 | 391 |
| 391 Loop on a wait-for-device with a very small timeout. On each | 392 Loop on a wait-for-device with a very small timeout. On each |
| 392 timeout, check the emulator process is still alive. | 393 timeout, check the emulator process is still alive. |
| 393 After confirming a wait-for-device can be successful, make sure | 394 After confirming a wait-for-device can be successful, make sure |
| 394 it returns the right answer. | 395 it returns the right answer. |
| 395 """ | 396 """ |
| 396 seconds_waited = 0 | 397 seconds_waited = 0 |
| 397 number_of_waits = 2 # Make sure we can wfd twice | 398 number_of_waits = 2 # Make sure we can wfd twice |
| 398 adb_cmd = "adb -s %s %s" % (self.device, 'wait-for-device') | 399 adb_cmd = "adb -s %s %s" % (self.device_serial, 'wait-for-device') |
| 399 while seconds_waited < self._LAUNCH_TIMEOUT: | 400 while seconds_waited < self._LAUNCH_TIMEOUT: |
| 400 try: | 401 try: |
| 401 run_command.RunCommand(adb_cmd, | 402 run_command.RunCommand(adb_cmd, |
| 402 timeout_time=self._WAITFORDEVICE_TIMEOUT, | 403 timeout_time=self._WAITFORDEVICE_TIMEOUT, |
| 403 retry_count=1) | 404 retry_count=1) |
| 404 number_of_waits -= 1 | 405 number_of_waits -= 1 |
| 405 if not number_of_waits: | 406 if not number_of_waits: |
| 406 break | 407 break |
| 407 except errors.WaitForResponseTimedOutError: | 408 except errors.WaitForResponseTimedOutError: |
| 408 seconds_waited += self._WAITFORDEVICE_TIMEOUT | 409 seconds_waited += self._WAITFORDEVICE_TIMEOUT |
| 409 adb_cmd = "adb -s %s %s" % (self.device, 'kill-server') | 410 adb_cmd = "adb -s %s %s" % (self.device_serial, 'kill-server') |
| 410 run_command.RunCommand(adb_cmd) | 411 run_command.RunCommand(adb_cmd) |
| 411 self.popen.poll() | 412 self.popen.poll() |
| 412 if self.popen.returncode != None: | 413 if self.popen.returncode != None: |
| 413 raise EmulatorLaunchException('EMULATOR DIED') | 414 raise EmulatorLaunchException('EMULATOR DIED') |
| 414 if seconds_waited >= self._LAUNCH_TIMEOUT: | 415 if seconds_waited >= self._LAUNCH_TIMEOUT: |
| 415 raise EmulatorLaunchException('TIMEOUT with wait-for-device') | 416 raise EmulatorLaunchException('TIMEOUT with wait-for-device') |
| 416 logging.info('Seconds waited on wait-for-device: %d', seconds_waited) | 417 logging.info('Seconds waited on wait-for-device: %d', seconds_waited) |
| 417 if wait_for_boot: | 418 if wait_for_boot: |
| 418 # Now that we checked for obvious problems, wait for a boot complete. | 419 # Now that we checked for obvious problems, wait for a boot complete. |
| 419 # Waiting for the package manager is sometimes problematic. | 420 # Waiting for the package manager is sometimes problematic. |
| 420 a = android_commands.AndroidCommands(self.device) | 421 d = device_utils.DeviceUtils(self.device_serial) |
| 421 a.WaitForSystemBootCompleted(self._WAITFORBOOT_TIMEOUT) | 422 d.old_interface.WaitForSystemBootCompleted(self._WAITFORBOOT_TIMEOUT) |
| 422 | 423 |
| 423 def Shutdown(self): | 424 def Shutdown(self): |
| 424 """Shuts down the process started by launch.""" | 425 """Shuts down the process started by launch.""" |
| 425 self._DeleteAVD() | 426 self._DeleteAVD() |
| 426 if self.popen: | 427 if self.popen: |
| 427 self.popen.poll() | 428 self.popen.poll() |
| 428 if self.popen.returncode == None: | 429 if self.popen.returncode == None: |
| 429 self.popen.kill() | 430 self.popen.kill() |
| 430 self.popen = None | 431 self.popen = None |
| 431 | 432 |
| 432 def _ShutdownOnSignal(self, _signum, _frame): | 433 def _ShutdownOnSignal(self, _signum, _frame): |
| 433 logging.critical('emulator _ShutdownOnSignal') | 434 logging.critical('emulator _ShutdownOnSignal') |
| 434 for sig in self._SIGNALS: | 435 for sig in self._SIGNALS: |
| 435 signal.signal(sig, signal.SIG_DFL) | 436 signal.signal(sig, signal.SIG_DFL) |
| 436 self.Shutdown() | 437 self.Shutdown() |
| 437 raise KeyboardInterrupt # print a stack | 438 raise KeyboardInterrupt # print a stack |
| 438 | 439 |
| 439 def _InstallKillHandler(self): | 440 def _InstallKillHandler(self): |
| 440 """Install a handler to kill the emulator when we exit unexpectedly.""" | 441 """Install a handler to kill the emulator when we exit unexpectedly.""" |
| 441 for sig in self._SIGNALS: | 442 for sig in self._SIGNALS: |
| 442 signal.signal(sig, self._ShutdownOnSignal) | 443 signal.signal(sig, self._ShutdownOnSignal) |
| OLD | NEW |