| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Provides an interface to start and stop Android emulator. | 6 """Provides an interface to start and stop Android emulator. |
| 7 | 7 |
| 8 Assumes system environment ANDROID_NDK_ROOT has been set. | 8 Assumes system environment ANDROID_NDK_ROOT has been set. |
| 9 | 9 |
| 10 Emulator: The class provides the methods to launch/shutdown the emulator with | 10 Emulator: The class provides the methods to launch/shutdown the emulator with |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 """Return our device name.""" | 107 """Return our device name.""" |
| 108 port = _GetAvailablePort() | 108 port = _GetAvailablePort() |
| 109 return ('emulator-%d' % port, port) | 109 return ('emulator-%d' % port, port) |
| 110 | 110 |
| 111 def Launch(self): | 111 def Launch(self): |
| 112 """Launches the emulator and waits for package manager to startup. | 112 """Launches the emulator and waits for package manager to startup. |
| 113 | 113 |
| 114 If fails, an exception will be raised. | 114 If fails, an exception will be raised. |
| 115 """ | 115 """ |
| 116 _KillAllEmulators() # just to be sure | 116 _KillAllEmulators() # just to be sure |
| 117 self._AggressiveImageCleanup() |
| 117 (self.device, port) = self._DeviceName() | 118 (self.device, port) = self._DeviceName() |
| 118 emulator_command = [ | 119 emulator_command = [ |
| 119 self.emulator, | 120 self.emulator, |
| 120 # Speed up emulator launch by 40%. Really. | 121 # Speed up emulator launch by 40%. Really. |
| 121 '-no-boot-anim', | 122 '-no-boot-anim', |
| 122 # The default /data size is 64M. | 123 # The default /data size is 64M. |
| 123 # That's not enough for 4 unit test bundles and their data. | 124 # That's not enough for 4 unit test bundles and their data. |
| 124 '-partition-size', '256', | 125 '-partition-size', '256', |
| 125 # ALWAYS wipe the data. We've seen cases where an emulator | 126 # ALWAYS wipe the data. We've seen cases where an emulator |
| 126 # gets 'stuck' if we don't do this (every thousand runs or | 127 # gets 'stuck' if we don't do this (every thousand runs or |
| 127 # so). | 128 # so). |
| 128 '-wipe-data', | 129 '-wipe-data', |
| 129 # Use a familiar name and port. | 130 # Use a familiar name and port. |
| 130 '-avd', 'buildbot', | 131 '-avd', 'buildbot', |
| 131 '-port', str(port)] | 132 '-port', str(port)] |
| 132 logging.info('Emulator launch command: %s', ' '.join(emulator_command)) | 133 logging.info('Emulator launch command: %s', ' '.join(emulator_command)) |
| 133 self.popen = subprocess.Popen(args=emulator_command, | 134 self.popen = subprocess.Popen(args=emulator_command, |
| 134 stderr=subprocess.STDOUT) | 135 stderr=subprocess.STDOUT) |
| 135 self._InstallKillHandler() | 136 self._InstallKillHandler() |
| 136 self._ConfirmLaunch() | 137 self._ConfirmLaunch() |
| 137 | 138 |
| 139 def _AggressiveImageCleanup(self): |
| 140 """Aggressive cleanup of emulator images. |
| 141 |
| 142 Experimentally it looks like our current emulator use on the bot |
| 143 leaves image files around in /tmp/android-$USER. If a "random" |
| 144 name gets reused, we choke with a 'File exists' error. |
| 145 TODO(jrg): is there a less hacky way to accomplish the same goal? |
| 146 """ |
| 147 logging.info('Aggressive Image Cleanup') |
| 148 emulator_imagedir = '/tmp/android-%s' % os.environ['USER'] |
| 149 for image in os.listdir(emulator_imagedir): |
| 150 full_name = os.path.join(emulator_imagedir, image) |
| 151 if 'emulator' in full_name: |
| 152 logging.info('Deleting emulator image %s', full_name) |
| 153 os.unlink(full_name) |
| 154 |
| 138 def _ConfirmLaunch(self, wait_for_boot=False): | 155 def _ConfirmLaunch(self, wait_for_boot=False): |
| 139 """Confirm the emulator launched properly. | 156 """Confirm the emulator launched properly. |
| 140 | 157 |
| 141 Loop on a wait-for-device with a very small timeout. On each | 158 Loop on a wait-for-device with a very small timeout. On each |
| 142 timeout, check the emulator process is still alive. | 159 timeout, check the emulator process is still alive. |
| 143 After confirming a wait-for-device can be successful, make sure | 160 After confirming a wait-for-device can be successful, make sure |
| 144 it returns the right answer. | 161 it returns the right answer. |
| 145 """ | 162 """ |
| 146 a = android_commands.AndroidCommands(self.device, False) | 163 a = android_commands.AndroidCommands(self.device, False) |
| 147 seconds_waited = 0 | 164 seconds_waited = 0 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 """Install a handler to kill the emulator when we exit unexpectedly.""" | 210 """Install a handler to kill the emulator when we exit unexpectedly.""" |
| 194 for sig in self._SIGNALS: | 211 for sig in self._SIGNALS: |
| 195 signal.signal(sig, self._ShutdownOnSignal) | 212 signal.signal(sig, self._ShutdownOnSignal) |
| 196 | 213 |
| 197 def main(argv): | 214 def main(argv): |
| 198 Emulator().launch() | 215 Emulator().launch() |
| 199 | 216 |
| 200 | 217 |
| 201 if __name__ == '__main__': | 218 if __name__ == '__main__': |
| 202 main(sys.argv) | 219 main(sys.argv) |
| OLD | NEW |