summaryrefslogtreecommitdiffstats
path: root/chromium/build/android/pylib/local/emulator/local_emulator_environment.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/build/android/pylib/local/emulator/local_emulator_environment.py')
-rw-r--r--chromium/build/android/pylib/local/emulator/local_emulator_environment.py131
1 files changed, 39 insertions, 92 deletions
diff --git a/chromium/build/android/pylib/local/emulator/local_emulator_environment.py b/chromium/build/android/pylib/local/emulator/local_emulator_environment.py
index cd81cf9c3a7..22470c035e6 100644
--- a/chromium/build/android/pylib/local/emulator/local_emulator_environment.py
+++ b/chromium/build/android/pylib/local/emulator/local_emulator_environment.py
@@ -2,20 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import contextlib
import logging
-import os
-import socket
-import stat
-from py_utils import tempfile_ext
-
-from devil.android.sdk import adb_wrapper
-from devil.utils import cmd_helper
-from devil.utils import timeout_retry
-
-from pylib import constants
+from devil.utils import parallelizer
from pylib.local.device import local_device_environment
+from pylib.local.emulator import avd
+
+# Mirroring https://bit.ly/2OjuxcS#23
+_MAX_ANDROID_EMULATORS = 16
class LocalEmulatorEnvironment(local_device_environment.LocalDeviceEnvironment):
@@ -23,99 +17,52 @@ class LocalEmulatorEnvironment(local_device_environment.LocalDeviceEnvironment):
def __init__(self, args, output_manager, error_func):
super(LocalEmulatorEnvironment, self).__init__(args, output_manager,
error_func)
- self._avd_name = args.avd_name
- self._emulator_home = (args.emulator_home
- or os.path.expanduser(os.path.join('~', '.android')))
-
- root_ini = os.path.join(self._emulator_home, 'avd',
- '%s.ini' % self._avd_name)
- if not os.path.exists(root_ini):
- error_func('Unable to find configuration for AVD %s at %s' %
- (self._avd_name, root_ini))
-
- self._emulator_path = os.path.join(constants.ANDROID_SDK_ROOT, 'emulator',
- 'emulator')
- if not os.path.exists(self._emulator_path):
- error_func('%s does not exist.' % self._emulator_path)
-
- self._emulator_proc = None
- self._emulator_serial = None
+ self._avd_config = avd.AvdConfig(args.avd_config)
+ if args.emulator_count < 1:
+ error_func('--emulator-count must be >= 1')
+ elif args.emulator_count >= _MAX_ANDROID_EMULATORS:
+ logging.warning('--emulator-count capped at 16.')
+ self._emulator_count = min(_MAX_ANDROID_EMULATORS, args.emulator_count)
+ self._emulator_window = args.emulator_window
+ self._emulator_instances = []
+ self._device_serials = []
#override
def SetUp(self):
- # Emulator start-up looks for the adb daemon. Make sure it's running.
- adb_wrapper.AdbWrapper.StartServer()
+ self._avd_config.Install()
- # Emulator start-up tries to check for the SDK root by looking for
- # platforms/ and platform-tools/. Ensure they exist.
- # See http://bit.ly/2YAkyFE for context.
- required_dirs = [
- os.path.join(constants.ANDROID_SDK_ROOT, 'platforms'),
- os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools'),
+ emulator_instances = [
+ self._avd_config.CreateInstance() for _ in range(self._emulator_count)
]
- for d in required_dirs:
- if not os.path.exists(d):
- os.makedirs(d)
- # The emulator requires that some files are writable.
- for dirname, _, filenames in os.walk(self._emulator_home):
- for f in filenames:
- path = os.path.join(dirname, f)
- if (os.lstat(path).st_mode &
- (stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) == stat.S_IRUSR):
- os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
+ def start_emulator_instance(e):
+ try:
+ e.Start(window=self._emulator_window)
+ return e
+ except avd.AvdException:
+ logging.exception('Failed to start emulator instance.')
+ return None
+
+ parallel_emulators = parallelizer.SyncParallelizer(emulator_instances)
+ self._emulator_instances = [
+ emu
+ for emu in parallel_emulators.pMap(start_emulator_instance).pGet(None)
+ if emu is not None
+ ]
+ self._device_serials = [e.serial for e in self._emulator_instances]
- self._emulator_proc, self._emulator_serial = self._StartInstance()
+ if not self._emulator_instances:
+ raise Exception('Failed to start any instances of the emulator.')
+ elif len(self._emulator_instances) < self._emulator_count:
+ logging.warning(
+ 'Running with fewer emulator instances than requested (%d vs %d)',
+ len(self._emulator_instances), self._emulator_count)
- logging.info('Emulator serial: %s', self._emulator_serial)
- self._device_serials = [self._emulator_serial]
super(LocalEmulatorEnvironment, self).SetUp()
- def _StartInstance(self):
- """Starts an AVD instance.
-
- Returns:
- A (Popen, str) 2-tuple that includes the process and serial.
- """
- # Start up the AVD.
- with tempfile_ext.TemporaryFileName() as socket_path, (contextlib.closing(
- socket.socket(socket.AF_UNIX))) as sock:
- sock.bind(socket_path)
- emulator_cmd = [
- self._emulator_path,
- '-avd',
- self._avd_name,
- '-report-console',
- 'unix:%s' % socket_path,
- '-read-only',
- '-no-window',
- ]
- emulator_env = {}
- if self._emulator_home:
- emulator_env['ANDROID_EMULATOR_HOME'] = self._emulator_home
- sock.listen(1)
- emulator_proc = cmd_helper.Popen(emulator_cmd, env=emulator_env)
-
- def listen_for_serial(s):
- logging.info('Waiting for connection from emulator.')
- with contextlib.closing(s.accept()[0]) as conn:
- val = conn.recv(1024)
- return 'emulator-%d' % int(val)
-
- try:
- emulator_serial = timeout_retry.Run(
- listen_for_serial, timeout=30, retries=0, args=[sock])
- except Exception:
- emulator_proc.terminate()
- raise
-
- return (emulator_proc, emulator_serial)
-
#override
def TearDown(self):
try:
super(LocalEmulatorEnvironment, self).TearDown()
finally:
- if self._emulator_proc:
- self._emulator_proc.terminate()
- self._emulator_proc.wait()
+ parallelizer.SyncParallelizer(self._emulator_instances).Stop()