summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/fuchsia/fvdl_target.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/fuchsia/fvdl_target.py')
-rw-r--r--third_party/libwebrtc/build/fuchsia/fvdl_target.py204
1 files changed, 204 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/fuchsia/fvdl_target.py b/third_party/libwebrtc/build/fuchsia/fvdl_target.py
new file mode 100644
index 0000000000..fa4fe4f004
--- /dev/null
+++ b/third_party/libwebrtc/build/fuchsia/fvdl_target.py
@@ -0,0 +1,204 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Implements commands for running and interacting with Fuchsia on FVDL."""
+
+import boot_data
+import common
+import emu_target
+import logging
+import os
+import re
+import subprocess
+import tempfile
+
+_SSH_KEY_DIR = os.path.expanduser('~/.ssh')
+_DEFAULT_SSH_PORT = 22
+_DEVICE_PROTO_TEMPLATE = """
+device_spec: {{
+ horizontal_resolution: 1024
+ vertical_resolution: 600
+ vm_heap: 192
+ ram: {ramsize}
+ cache: 32
+ screen_density: 240
+}}
+"""
+
+
+def GetTargetType():
+ return FvdlTarget
+
+
+class EmulatorNetworkNotFoundError(Exception):
+ """Raised when emulator's address cannot be found"""
+ pass
+
+
+class FvdlTarget(emu_target.EmuTarget):
+ EMULATOR_NAME = 'aemu'
+ _FVDL_PATH = os.path.join(common.SDK_ROOT, 'tools', 'x64', 'fvdl')
+
+ def __init__(self, out_dir, target_cpu, system_log_file, require_kvm,
+ enable_graphics, hardware_gpu, with_network, ram_size_mb):
+ super(FvdlTarget, self).__init__(out_dir, target_cpu, system_log_file)
+ self._require_kvm = require_kvm
+ self._enable_graphics = enable_graphics
+ self._hardware_gpu = hardware_gpu
+ self._with_network = with_network
+ self._ram_size_mb = ram_size_mb
+
+ self._host = None
+ self._pid = None
+
+ # Use a temp file for vdl output.
+ self._vdl_output_file = tempfile.NamedTemporaryFile()
+
+ # Use a temp file for the device proto and write the ram size.
+ self._device_proto_file = tempfile.NamedTemporaryFile()
+ with open(self._device_proto_file.name, 'w') as file:
+ file.write(_DEVICE_PROTO_TEMPLATE.format(ramsize=self._ram_size_mb))
+
+ @staticmethod
+ def CreateFromArgs(args):
+ return FvdlTarget(args.out_dir, args.target_cpu, args.system_log_file,
+ args.require_kvm, args.enable_graphics, args.hardware_gpu,
+ args.with_network, args.ram_size_mb)
+
+ @staticmethod
+ def RegisterArgs(arg_parser):
+ fvdl_args = arg_parser.add_argument_group('fvdl', 'FVDL arguments')
+ fvdl_args.add_argument('--with-network',
+ action='store_true',
+ default=False,
+ help='Run emulator with emulated nic via tun/tap.')
+
+ def _BuildCommand(self):
+ boot_data.ProvisionSSH()
+ self._host_ssh_port = common.GetAvailableTcpPort()
+ kernel_image = common.EnsurePathExists(
+ boot_data.GetTargetFile('qemu-kernel.kernel', self._GetTargetSdkArch(),
+ boot_data.TARGET_TYPE_QEMU))
+ zbi_image = common.EnsurePathExists(
+ boot_data.GetTargetFile('zircon-a.zbi', self._GetTargetSdkArch(),
+ boot_data.TARGET_TYPE_QEMU))
+ fvm_image = common.EnsurePathExists(
+ boot_data.GetTargetFile('storage-full.blk', self._GetTargetSdkArch(),
+ boot_data.TARGET_TYPE_QEMU))
+ aemu_path = common.EnsurePathExists(
+ os.path.join(common.GetEmuRootForPlatform(self.EMULATOR_NAME),
+ 'emulator'))
+
+ emu_command = [
+ self._FVDL_PATH,
+ '--sdk',
+ 'start',
+ '--nopackageserver',
+ '--nointeractive',
+
+ # Host port mapping for user-networking mode.
+ '--port-map',
+ 'hostfwd=tcp::{}-:22'.format(self._host_ssh_port),
+
+ # no-interactive requires a --vdl-output flag to shutdown the emulator.
+ '--vdl-output',
+ self._vdl_output_file.name,
+
+ # Use existing images instead of downloading new ones.
+ '--kernel-image',
+ kernel_image,
+ '--zbi-image',
+ zbi_image,
+ '--fvm-image',
+ fvm_image,
+ '--image-architecture',
+ self._target_cpu,
+
+ # Use an existing emulator checked out by Chromium.
+ '--aemu-path',
+ aemu_path,
+
+ # Use this flag and temp file to define ram size.
+ '--device-proto',
+ self._device_proto_file.name
+ ]
+
+ if not self._require_kvm:
+ emu_command.append('--noacceleration')
+ if not self._enable_graphics:
+ emu_command.append('--headless')
+ if self._hardware_gpu:
+ emu_command.append('--host-gpu')
+ if self._with_network:
+ emu_command.append('-N')
+
+ logging.info('FVDL command: ' + ' '.join(emu_command))
+
+ return emu_command
+
+ def _WaitUntilReady(self):
+ # Indicates the FVDL command finished running.
+ self._emu_process.communicate()
+ super(FvdlTarget, self)._WaitUntilReady()
+
+ def _IsEmuStillRunning(self):
+ if not self._pid:
+ try:
+ with open(self._vdl_output_file.name) as vdl_file:
+ for line in vdl_file:
+ if 'pid' in line:
+ match = re.match(r'.*pid:\s*(\d*).*', line)
+ if match:
+ self._pid = match.group(1)
+ except IOError:
+ logging.error('vdl_output file no longer found. '
+ 'Cannot get emulator pid.')
+ return False
+ if subprocess.check_output(['ps', '-p', self._pid, 'o', 'comm=']):
+ return True
+ logging.error('Emulator pid no longer found. Emulator must be down.')
+ return False
+
+ def _GetEndpoint(self):
+ if self._with_network:
+ return self._GetNetworkAddress()
+ return ('localhost', self._host_ssh_port)
+
+ def _GetNetworkAddress(self):
+ if self._host:
+ return (self._host, _DEFAULT_SSH_PORT)
+ try:
+ with open(self._vdl_output_file.name) as vdl_file:
+ for line in vdl_file:
+ if 'network_address' in line:
+ address = re.match(r'.*network_address:\s*"\[(.*)\]".*', line)
+ if address:
+ self._host = address.group(1)
+ return (self._host, _DEFAULT_SSH_PORT)
+ logging.error('Network address not found.')
+ raise EmulatorNetworkNotFoundError()
+ except IOError as e:
+ logging.error('vdl_output file not found. Cannot get network address.')
+ raise
+
+ def Shutdown(self):
+ if not self._emu_process:
+ logging.error('%s did not start' % (self.EMULATOR_NAME))
+ return
+ femu_command = [
+ self._FVDL_PATH, '--sdk', 'kill', '--launched-proto',
+ self._vdl_output_file.name
+ ]
+ femu_process = subprocess.Popen(femu_command)
+ returncode = femu_process.wait()
+ if returncode == 0:
+ logging.info('FVDL shutdown successfully')
+ else:
+ logging.info('FVDL kill returned error status {}'.format(returncode))
+ emu_target.LogProcessStatistics('proc_stat_end_log')
+ emu_target.LogSystemStatistics('system_statistics_end_log')
+ self._vdl_output_file.close()
+ self._device_proto_file.close()
+
+ def _GetSshConfigPath(self):
+ return boot_data.GetSSHConfigPath()