1#!/usr/bin/env vpython3 2# Copyright 2022 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""Provides a class for managing emulators.""" 6 7import argparse 8import logging 9import sys 10 11from contextlib import AbstractContextManager 12 13from common import catch_sigterm, register_log_args, wait_for_sigterm 14from ffx_emulator import FfxEmulator 15 16 17def register_emulator_args(parser: argparse.ArgumentParser, 18 enable_graphics: bool = False) -> None: 19 """Register emulator specific arguments.""" 20 femu_args = parser.add_argument_group('emulator', 21 'emulator startup arguments.') 22 femu_args.add_argument('--custom-image', 23 dest='product_bundle', 24 help='Backwards compatible flag that specifies an ' 25 'image used for booting up the emulator.') 26 if enable_graphics: 27 femu_args.add_argument('--disable-graphics', 28 action='store_false', 29 dest='enable_graphics', 30 help='Start emulator in headless mode.') 31 else: 32 femu_args.add_argument('--enable-graphics', 33 action='store_true', 34 help='Start emulator with graphics.') 35 femu_args.add_argument( 36 '--hardware-gpu', 37 action='store_true', 38 help='Use host GPU hardware instead of Swiftshader.') 39 femu_args.add_argument( 40 '--product', 41 help='Specify a product bundle used for booting the ' 42 'emulator. Defaults to the terminal product.') 43 femu_args.add_argument('--with-network', 44 action='store_true', 45 help='Run emulator with emulated nic via tun/tap.') 46 femu_args.add_argument('--everlasting', 47 action='store_true', 48 help='If the emulator should be long-living.') 49 femu_args.add_argument( 50 '--device-spec', 51 help='Configure the virtual device to use. They are usually defined in ' 52 'the product-bundle/virtual_devices/manifest.json. If this flag is not ' 53 'provided or is an empty string, ffx emu will decide the recommended ' 54 'spec.') 55 56 57def create_emulator_from_args( 58 args: argparse.Namespace) -> AbstractContextManager: 59 """Helper method for initializing an FfxEmulator class with parsed 60 arguments.""" 61 return FfxEmulator(args) 62 63 64def main(): 65 """Stand-alone function for starting an emulator.""" 66 67 catch_sigterm() 68 logging.basicConfig(level=logging.INFO) 69 parser = argparse.ArgumentParser() 70 register_emulator_args(parser, True) 71 register_log_args(parser) 72 parser.add_argument('--target-id-only', 73 action='store_true', 74 help='Write only the target emulator id to the ' \ 75 'stdout. It is usually useful in the unattended ' \ 76 'environment.') 77 args = parser.parse_args() 78 with create_emulator_from_args(args) as target_id: 79 if args.target_id_only: 80 print(target_id, flush=True) 81 else: 82 logging.info( 83 'Emulator successfully started. You can now run Chrome ' 84 'Fuchsia tests with --target-id=%s to target this emulator.', 85 target_id) 86 wait_for_sigterm('shutting down the emulator.') 87 88 89if __name__ == '__main__': 90 sys.exit(main()) 91