1342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#!/usr/bin/env python
2342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Copyright (c) 2013 The Chromium Authors. All rights reserved.
3342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# Use of this source code is governed by a BSD-style license that can be
4342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch# found in the LICENSE file.
5342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
6342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch"""Launches Android Virtual Devices with a set configuration for testing Chrome.
7342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
8342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochThe script will launch a specified number of Android Virtual Devices (AVD's).
9342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch"""
10342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
11342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport argparse
12342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport logging
13342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport os
14342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport re
15342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport sys
16342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
17342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport devil_chromium
18342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochimport install_emulator_deps
19342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
20342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom devil.utils import cmd_helper
21342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom pylib import constants
22342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochfrom pylib.utils import emulator
23342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
24342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochdef main(argv):
25342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  # ANDROID_SDK_ROOT needs to be set to the location of the SDK used to launch
26342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  # the emulator to find the system images upon launch.
27342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  emulator_sdk = constants.ANDROID_SDK_ROOT
28342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  os.environ['ANDROID_SDK_ROOT'] = emulator_sdk
29342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
30342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  arg_parser = argparse.ArgumentParser(description='AVD script.')
31342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  sub_parsers = arg_parser.add_subparsers(title='subparser', dest='command')
32342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  sub_parsers.add_parser(
33342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      'kill', help='Shutdown all existing emulators')
34342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  sub_parsers.add_parser(
35342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      'delete', help='Deleting all the avd files')
36342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  wait_parser = sub_parsers.add_parser(
37342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      'wait', help='Wait for emulators to finish booting')
38342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  wait_parser.add_argument('-n', '--num', dest='wait_num',
39342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                           help='Number of emulators to wait for', type=int,
40342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                           default=1)
41342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser = sub_parsers.add_parser('run', help='Run emulators')
42342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--name', help='Optinaly, name of existing AVD to '
43342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          'launch. If not specified, AVD\'s will be created')
44342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('-n', '--num', dest='emulator_count',
45342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Number of emulators to launch (default is 1).',
46342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          type=int, default='1')
47342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--abi', default='x86',
48342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Platform of emulators to launch (x86 default)')
49342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--api-level', dest='api_level',
50342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='API level for the image',
51342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          type=int, default=constants.ANDROID_SDK_VERSION)
52342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--sdcard-size', dest='sdcard_size',
53342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          default=emulator.DEFAULT_SDCARD_SIZE,
54342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Set sdcard size of the emulators'
55342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          ' e.g. --sdcard-size=512M')
56342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--partition-size', dest='partition_size',
57342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          default=emulator.DEFAULT_STORAGE_SIZE,
58342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Default internal storage size'
59342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          ' e.g. --partition-size=1024M')
60342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--launch-without-kill', action='store_false',
61342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          dest='kill_and_launch', default=True,
62342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Kill all emulators at launch')
63342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--enable-kvm', action='store_true',
64342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          dest='enable_kvm', default=False,
65342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Enable kvm for faster x86 emulator run')
66342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  run_parser.add_argument('--headless', action='store_true',
67342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          dest='headless', default=False,
68342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                          help='Launch an emulator with no UI.')
69342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
70342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  arguments = arg_parser.parse_args(argv[1:])
71342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
72342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  logging.root.setLevel(logging.INFO)
73342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
74342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  devil_chromium.Initialize()
75342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
76342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  if arguments.command == 'kill':
77342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    logging.info('Killing all existing emulator and existing the program')
78342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    emulator.KillAllEmulators()
79342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  elif arguments.command == 'delete':
80342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    emulator.DeleteAllTempAVDs()
81342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  elif arguments.command == 'wait':
82342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    emulator.WaitForEmulatorLaunch(arguments.wait_num)
83342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  else:
84342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    # Check if SDK exist in ANDROID_SDK_ROOT
85342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if not install_emulator_deps.CheckSDK():
86342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      raise Exception('Emulator SDK not installed in %s'
87342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                       % constants.ANDROID_SDK_ROOT)
88342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
89342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    # Check if KVM is enabled for x86 AVD
90342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if arguments.abi == 'x86':
91342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      if not install_emulator_deps.CheckKVM():
92342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        logging.warning('KVM is not installed or enabled')
93342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        arguments.enable_kvm = False
94342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
95342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    # Check if targeted system image exist
96342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if not install_emulator_deps.CheckSystemImage(arguments.abi,
97342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                                                  arguments.api_level):
98342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      logging.critical('ERROR: System image for %s AVD not installed. Run '
99342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                       'install_emulator_deps.py', arguments.abi)
100342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      return 1
101342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
102342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    # If AVD is specified, check that the SDK has the required target. If not,
103342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    # check that the SDK has the desired target for the temporary AVD's.
104342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    api_level = arguments.api_level
105342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if arguments.name:
106342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      android = os.path.join(constants.ANDROID_SDK_ROOT, 'tools',
107342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                             'android')
108342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      avds_output = cmd_helper.GetCmdOutput([android, 'list', 'avd'])
109342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      names = re.findall(r'Name: (\w+)', avds_output)
110342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      api_levels = re.findall(r'API level (\d+)', avds_output)
111342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      try:
112342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        avd_index = names.index(arguments.name)
113342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      except ValueError:
114342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        logging.critical('ERROR: Specified AVD %s does not exist.',
115342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                         arguments.name)
116342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        return 1
117342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      api_level = int(api_levels[avd_index])
118342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
119342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if not install_emulator_deps.CheckSDKPlatform(api_level):
120342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      logging.critical('ERROR: Emulator SDK missing required target for API %d.'
121342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                       ' Run install_emulator_deps.py.')
122342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      return 1
123342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
124342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    if arguments.name:
125342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      emulator.LaunchEmulator(
126342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          arguments.name,
127342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          arguments.abi,
128342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          enable_kvm=arguments.enable_kvm,
129342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          kill_and_launch=arguments.reset_and_launch,
130342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          sdcard_size=arguments.sdcard_size,
131342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          storage_size=arguments.partition_size,
132342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          headless=arguments.headless
133342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      )
134342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    else:
135342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      emulator.LaunchTempEmulators(
136342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          arguments.emulator_count,
137342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          arguments.abi,
138342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          arguments.api_level,
139342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          enable_kvm=arguments.enable_kvm,
140342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          kill_and_launch=arguments.kill_and_launch,
141342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          sdcard_size=arguments.sdcard_size,
142342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          storage_size=arguments.partition_size,
143342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          wait_for_boot=True,
144342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          headless=arguments.headless
145342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      )
146342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    logging.info('Emulator launch completed')
147342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  return 0
148342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
149342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochif __name__ == '__main__':
150342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  sys.exit(main(sys.argv))
151