xref: /aosp_15_r20/tools/acloud/internal/lib/goldfish_utils.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
1*800a58d9SAndroid Build Coastguard Worker# Copyright 2021 - The Android Open Source Project
2*800a58d9SAndroid Build Coastguard Worker#
3*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*800a58d9SAndroid Build Coastguard Worker#
7*800a58d9SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*800a58d9SAndroid Build Coastguard Worker#
9*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*800a58d9SAndroid Build Coastguard Worker# limitations under the License.
14*800a58d9SAndroid Build Coastguard Worker
15*800a58d9SAndroid Build Coastguard Worker"""Utility functions that process goldfish images and arguments."""
16*800a58d9SAndroid Build Coastguard Worker
17*800a58d9SAndroid Build Coastguard Workerimport os
18*800a58d9SAndroid Build Coastguard Workerimport re
19*800a58d9SAndroid Build Coastguard Workerimport shutil
20*800a58d9SAndroid Build Coastguard Worker
21*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors
22*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants
23*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import ota_tools
24*800a58d9SAndroid Build Coastguard Worker
25*800a58d9SAndroid Build Coastguard Worker
26*800a58d9SAndroid Build Coastguard Worker# File names under working directory.
27*800a58d9SAndroid Build Coastguard Worker_UNPACK_DIR_NAME = "unpacked_boot_img"
28*800a58d9SAndroid Build Coastguard Worker_MIXED_RAMDISK_IMAGE_NAME = "mixed_ramdisk"
29*800a58d9SAndroid Build Coastguard Worker# File names in unpacked boot image.
30*800a58d9SAndroid Build Coastguard Worker_UNPACKED_KERNEL_IMAGE_NAME = "kernel"
31*800a58d9SAndroid Build Coastguard Worker_UNPACKED_RAMDISK_IMAGE_NAME = "ramdisk"
32*800a58d9SAndroid Build Coastguard Worker# File names in a build environment or an SDK repository.
33*800a58d9SAndroid Build Coastguard WorkerSYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
34*800a58d9SAndroid Build Coastguard WorkerVERIFIED_BOOT_PARAMS_FILE_NAME = "VerifiedBootParams.textproto"
35*800a58d9SAndroid Build Coastguard Worker_SDK_REPO_SYSTEM_IMAGE_NAME = "system.img"
36*800a58d9SAndroid Build Coastguard Worker_MISC_INFO_FILE_NAME = "misc_info.txt"
37*800a58d9SAndroid Build Coastguard Worker_SYSTEM_QEMU_CONFIG_FILE_NAME = "system-qemu-config.txt"
38*800a58d9SAndroid Build Coastguard Worker# File names in the search order of emulator.
39*800a58d9SAndroid Build Coastguard Worker_DISK_IMAGE_NAMES = (SYSTEM_QEMU_IMAGE_NAME, _SDK_REPO_SYSTEM_IMAGE_NAME)
40*800a58d9SAndroid Build Coastguard Worker_KERNEL_IMAGE_NAMES = ("kernel-ranchu", "kernel-ranchu-64", "kernel")
41*800a58d9SAndroid Build Coastguard Worker_RAMDISK_IMAGE_NAMES = ("ramdisk-qemu.img", "ramdisk.img")
42*800a58d9SAndroid Build Coastguard Worker_SYSTEM_DLKM_IMAGE_NAMES = (
43*800a58d9SAndroid Build Coastguard Worker    "system_dlkm.flatten.erofs.img",  # GKI artifact
44*800a58d9SAndroid Build Coastguard Worker    "system_dlkm.flatten.ext4.img",  # GKI artifact
45*800a58d9SAndroid Build Coastguard Worker    "system_dlkm.img",  # goldfish artifact
46*800a58d9SAndroid Build Coastguard Worker)
47*800a58d9SAndroid Build Coastguard Worker# Remote host instance name.
48*800a58d9SAndroid Build Coastguard Worker# hostname can be a domain name. "-" in hostname must be replaced with "_".
49*800a58d9SAndroid Build Coastguard Worker_REMOTE_HOST_INSTANCE_NAME_FORMAT = (
50*800a58d9SAndroid Build Coastguard Worker    "host-goldfish-%(hostname)s-%(console_port)s-%(build_info)s")
51*800a58d9SAndroid Build Coastguard Worker_REMOTE_HOST_INSTANCE_NAME_PATTERN = re.compile(
52*800a58d9SAndroid Build Coastguard Worker    r"host-goldfish-(?P<hostname>[\w.]+)-(?P<console_port>\d+)-.+")
53*800a58d9SAndroid Build Coastguard Worker
54*800a58d9SAndroid Build Coastguard Worker
55*800a58d9SAndroid Build Coastguard Workerdef _FindFileByNames(parent_dir, names):
56*800a58d9SAndroid Build Coastguard Worker    """Find file under a directory by names.
57*800a58d9SAndroid Build Coastguard Worker
58*800a58d9SAndroid Build Coastguard Worker    Args:
59*800a58d9SAndroid Build Coastguard Worker        parent_dir: The directory to find the file in.
60*800a58d9SAndroid Build Coastguard Worker        names: A list of file names.
61*800a58d9SAndroid Build Coastguard Worker
62*800a58d9SAndroid Build Coastguard Worker    Returns:
63*800a58d9SAndroid Build Coastguard Worker        The path to the first existing file in the list.
64*800a58d9SAndroid Build Coastguard Worker
65*800a58d9SAndroid Build Coastguard Worker    Raises:
66*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if none of the files exist.
67*800a58d9SAndroid Build Coastguard Worker    """
68*800a58d9SAndroid Build Coastguard Worker    for name in names:
69*800a58d9SAndroid Build Coastguard Worker        path = os.path.join(parent_dir, name)
70*800a58d9SAndroid Build Coastguard Worker        if os.path.isfile(path):
71*800a58d9SAndroid Build Coastguard Worker            return path
72*800a58d9SAndroid Build Coastguard Worker    raise errors.GetLocalImageError("No %s in %s." %
73*800a58d9SAndroid Build Coastguard Worker                                    (", ".join(names), parent_dir))
74*800a58d9SAndroid Build Coastguard Worker
75*800a58d9SAndroid Build Coastguard Worker
76*800a58d9SAndroid Build Coastguard Workerdef _UnpackBootImage(output_dir, boot_image_path, ota):
77*800a58d9SAndroid Build Coastguard Worker    """Unpack a boot image and find kernel images.
78*800a58d9SAndroid Build Coastguard Worker
79*800a58d9SAndroid Build Coastguard Worker    Args:
80*800a58d9SAndroid Build Coastguard Worker        output_dir: The directory where the boot image is unpacked.
81*800a58d9SAndroid Build Coastguard Worker        boot_image_path: The path to the boot image.
82*800a58d9SAndroid Build Coastguard Worker        ota: An instance of ota_tools.OtaTools.
83*800a58d9SAndroid Build Coastguard Worker
84*800a58d9SAndroid Build Coastguard Worker    Returns:
85*800a58d9SAndroid Build Coastguard Worker        The kernel image path and the ramdisk image path.
86*800a58d9SAndroid Build Coastguard Worker
87*800a58d9SAndroid Build Coastguard Worker    Raises:
88*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if the kernel or the ramdisk is not found.
89*800a58d9SAndroid Build Coastguard Worker    """
90*800a58d9SAndroid Build Coastguard Worker    ota.UnpackBootImg(output_dir, boot_image_path)
91*800a58d9SAndroid Build Coastguard Worker
92*800a58d9SAndroid Build Coastguard Worker    kernel_path = os.path.join(output_dir, _UNPACKED_KERNEL_IMAGE_NAME)
93*800a58d9SAndroid Build Coastguard Worker    ramdisk_path = os.path.join(output_dir, _UNPACKED_RAMDISK_IMAGE_NAME)
94*800a58d9SAndroid Build Coastguard Worker    if not os.path.isfile(kernel_path):
95*800a58d9SAndroid Build Coastguard Worker        raise errors.GetLocalImageError("No kernel in %s." % boot_image_path)
96*800a58d9SAndroid Build Coastguard Worker    if not os.path.isfile(ramdisk_path):
97*800a58d9SAndroid Build Coastguard Worker        raise errors.GetLocalImageError("No ramdisk in %s." % boot_image_path)
98*800a58d9SAndroid Build Coastguard Worker    return kernel_path, ramdisk_path
99*800a58d9SAndroid Build Coastguard Worker
100*800a58d9SAndroid Build Coastguard Worker
101*800a58d9SAndroid Build Coastguard Workerdef _MixRamdiskImages(output_path, original_ramdisk_path,
102*800a58d9SAndroid Build Coastguard Worker                      boot_ramdisk_path):
103*800a58d9SAndroid Build Coastguard Worker    """Mix an emulator ramdisk with a boot ramdisk.
104*800a58d9SAndroid Build Coastguard Worker
105*800a58d9SAndroid Build Coastguard Worker    An emulator ramdisk consists of a boot ramdisk and a vendor ramdisk.
106*800a58d9SAndroid Build Coastguard Worker    This method overlays a new boot ramdisk on the emulator ramdisk by
107*800a58d9SAndroid Build Coastguard Worker    concatenating them.
108*800a58d9SAndroid Build Coastguard Worker
109*800a58d9SAndroid Build Coastguard Worker    Args:
110*800a58d9SAndroid Build Coastguard Worker        output_path: The path to the output ramdisk.
111*800a58d9SAndroid Build Coastguard Worker        original_ramdisk_path: The path to the emulator ramdisk.
112*800a58d9SAndroid Build Coastguard Worker        boot_ramdisk_path: The path to the boot ramdisk.
113*800a58d9SAndroid Build Coastguard Worker    """
114*800a58d9SAndroid Build Coastguard Worker    with open(output_path, "wb") as mixed_ramdisk:
115*800a58d9SAndroid Build Coastguard Worker        with open(original_ramdisk_path, "rb") as ramdisk:
116*800a58d9SAndroid Build Coastguard Worker            shutil.copyfileobj(ramdisk, mixed_ramdisk)
117*800a58d9SAndroid Build Coastguard Worker        with open(boot_ramdisk_path, "rb") as ramdisk:
118*800a58d9SAndroid Build Coastguard Worker            shutil.copyfileobj(ramdisk, mixed_ramdisk)
119*800a58d9SAndroid Build Coastguard Worker
120*800a58d9SAndroid Build Coastguard Worker
121*800a58d9SAndroid Build Coastguard Workerdef MixWithBootImage(output_dir, image_dir, boot_image_path, ota):
122*800a58d9SAndroid Build Coastguard Worker    """Mix emulator kernel images with a boot image.
123*800a58d9SAndroid Build Coastguard Worker
124*800a58d9SAndroid Build Coastguard Worker    Args:
125*800a58d9SAndroid Build Coastguard Worker        output_dir: The directory containing the output and intermediate files.
126*800a58d9SAndroid Build Coastguard Worker        image_dir: The directory containing emulator kernel and ramdisk images.
127*800a58d9SAndroid Build Coastguard Worker        boot_image_path: The path to the boot image.
128*800a58d9SAndroid Build Coastguard Worker        ota: An instance of ota_tools.OtaTools.
129*800a58d9SAndroid Build Coastguard Worker
130*800a58d9SAndroid Build Coastguard Worker    Returns:
131*800a58d9SAndroid Build Coastguard Worker        The paths to the kernel and ramdisk images in output_dir.
132*800a58d9SAndroid Build Coastguard Worker
133*800a58d9SAndroid Build Coastguard Worker    Raises:
134*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if any image is not found.
135*800a58d9SAndroid Build Coastguard Worker    """
136*800a58d9SAndroid Build Coastguard Worker    unpack_dir = os.path.join(output_dir, _UNPACK_DIR_NAME)
137*800a58d9SAndroid Build Coastguard Worker    if os.path.exists(unpack_dir):
138*800a58d9SAndroid Build Coastguard Worker        shutil.rmtree(unpack_dir)
139*800a58d9SAndroid Build Coastguard Worker    os.makedirs(unpack_dir, exist_ok=True)
140*800a58d9SAndroid Build Coastguard Worker
141*800a58d9SAndroid Build Coastguard Worker    kernel_path, boot_ramdisk_path = _UnpackBootImage(
142*800a58d9SAndroid Build Coastguard Worker        unpack_dir, boot_image_path, ota)
143*800a58d9SAndroid Build Coastguard Worker    # The ramdisk unpacked from boot_image_path does not include emulator's
144*800a58d9SAndroid Build Coastguard Worker    # kernel modules. The ramdisk in image_dir contains the modules. This
145*800a58d9SAndroid Build Coastguard Worker    # method mixes the two ramdisks.
146*800a58d9SAndroid Build Coastguard Worker    mixed_ramdisk_path = os.path.join(output_dir, _MIXED_RAMDISK_IMAGE_NAME)
147*800a58d9SAndroid Build Coastguard Worker    original_ramdisk_path = _FindFileByNames(image_dir, _RAMDISK_IMAGE_NAMES)
148*800a58d9SAndroid Build Coastguard Worker    _MixRamdiskImages(mixed_ramdisk_path, original_ramdisk_path,
149*800a58d9SAndroid Build Coastguard Worker                      boot_ramdisk_path)
150*800a58d9SAndroid Build Coastguard Worker    return kernel_path, mixed_ramdisk_path
151*800a58d9SAndroid Build Coastguard Worker
152*800a58d9SAndroid Build Coastguard Worker
153*800a58d9SAndroid Build Coastguard Workerdef FindKernelImages(image_dir):
154*800a58d9SAndroid Build Coastguard Worker    """Find emulator kernel images in a directory.
155*800a58d9SAndroid Build Coastguard Worker
156*800a58d9SAndroid Build Coastguard Worker    Args:
157*800a58d9SAndroid Build Coastguard Worker        image_dir: The directory to find the images in.
158*800a58d9SAndroid Build Coastguard Worker
159*800a58d9SAndroid Build Coastguard Worker    Returns:
160*800a58d9SAndroid Build Coastguard Worker        The paths to the kernel image and the ramdisk image.
161*800a58d9SAndroid Build Coastguard Worker
162*800a58d9SAndroid Build Coastguard Worker    Raises:
163*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if any image is not found.
164*800a58d9SAndroid Build Coastguard Worker    """
165*800a58d9SAndroid Build Coastguard Worker    return (_FindFileByNames(image_dir, _KERNEL_IMAGE_NAMES),
166*800a58d9SAndroid Build Coastguard Worker            _FindFileByNames(image_dir, _RAMDISK_IMAGE_NAMES))
167*800a58d9SAndroid Build Coastguard Worker
168*800a58d9SAndroid Build Coastguard Worker
169*800a58d9SAndroid Build Coastguard Workerdef FindSystemDlkmImage(search_path):
170*800a58d9SAndroid Build Coastguard Worker    """Find system_dlkm image in a path.
171*800a58d9SAndroid Build Coastguard Worker
172*800a58d9SAndroid Build Coastguard Worker    Args:
173*800a58d9SAndroid Build Coastguard Worker        search_path: A path to an image file or an image directory.
174*800a58d9SAndroid Build Coastguard Worker
175*800a58d9SAndroid Build Coastguard Worker    Returns:
176*800a58d9SAndroid Build Coastguard Worker        The system_dlkm image path.
177*800a58d9SAndroid Build Coastguard Worker
178*800a58d9SAndroid Build Coastguard Worker    Raises:
179*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if search_path does not contain a
180*800a58d9SAndroid Build Coastguard Worker        system_dlkm image.
181*800a58d9SAndroid Build Coastguard Worker    """
182*800a58d9SAndroid Build Coastguard Worker    return (search_path if os.path.isfile(search_path) else
183*800a58d9SAndroid Build Coastguard Worker            _FindFileByNames(search_path, _SYSTEM_DLKM_IMAGE_NAMES))
184*800a58d9SAndroid Build Coastguard Worker
185*800a58d9SAndroid Build Coastguard Worker
186*800a58d9SAndroid Build Coastguard Workerdef FindDiskImage(image_dir):
187*800a58d9SAndroid Build Coastguard Worker    """Find an emulator disk image in a directory.
188*800a58d9SAndroid Build Coastguard Worker
189*800a58d9SAndroid Build Coastguard Worker    Args:
190*800a58d9SAndroid Build Coastguard Worker        image_dir: The directory to find the image in.
191*800a58d9SAndroid Build Coastguard Worker
192*800a58d9SAndroid Build Coastguard Worker    Returns:
193*800a58d9SAndroid Build Coastguard Worker        The path to the disk image.
194*800a58d9SAndroid Build Coastguard Worker
195*800a58d9SAndroid Build Coastguard Worker    Raises:
196*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if the image is not found.
197*800a58d9SAndroid Build Coastguard Worker    """
198*800a58d9SAndroid Build Coastguard Worker    return _FindFileByNames(image_dir, _DISK_IMAGE_NAMES)
199*800a58d9SAndroid Build Coastguard Worker
200*800a58d9SAndroid Build Coastguard Worker
201*800a58d9SAndroid Build Coastguard Workerdef MixDiskImage(output_dir, image_dir, system_image_path,
202*800a58d9SAndroid Build Coastguard Worker                 system_dlkm_image_path, ota):
203*800a58d9SAndroid Build Coastguard Worker    """Mix emulator images into a disk image.
204*800a58d9SAndroid Build Coastguard Worker
205*800a58d9SAndroid Build Coastguard Worker    Args:
206*800a58d9SAndroid Build Coastguard Worker        output_dir: The path to the output directory.
207*800a58d9SAndroid Build Coastguard Worker        image_dir: The input directory that provides images except
208*800a58d9SAndroid Build Coastguard Worker                   system.img.
209*800a58d9SAndroid Build Coastguard Worker        system_image_path: A string or None, the system image path.
210*800a58d9SAndroid Build Coastguard Worker        system_dlkm_image_path: A string or None, the system_dlkm image path.
211*800a58d9SAndroid Build Coastguard Worker        ota: An instance of ota_tools.OtaTools.
212*800a58d9SAndroid Build Coastguard Worker
213*800a58d9SAndroid Build Coastguard Worker    Returns:
214*800a58d9SAndroid Build Coastguard Worker        The path to the mixed disk image in output_dir.
215*800a58d9SAndroid Build Coastguard Worker
216*800a58d9SAndroid Build Coastguard Worker    Raises:
217*800a58d9SAndroid Build Coastguard Worker        errors.GetLocalImageError if any required file is not found.
218*800a58d9SAndroid Build Coastguard Worker    """
219*800a58d9SAndroid Build Coastguard Worker    os.makedirs(output_dir, exist_ok=True)
220*800a58d9SAndroid Build Coastguard Worker
221*800a58d9SAndroid Build Coastguard Worker    # Create the super image.
222*800a58d9SAndroid Build Coastguard Worker    mixed_super_image_path = os.path.join(output_dir, "mixed_super.img")
223*800a58d9SAndroid Build Coastguard Worker    ota.BuildSuperImage(
224*800a58d9SAndroid Build Coastguard Worker        mixed_super_image_path,
225*800a58d9SAndroid Build Coastguard Worker        _FindFileByNames(image_dir, [_MISC_INFO_FILE_NAME]),
226*800a58d9SAndroid Build Coastguard Worker        lambda partition: ota_tools.GetImageForPartition(
227*800a58d9SAndroid Build Coastguard Worker            partition, image_dir,
228*800a58d9SAndroid Build Coastguard Worker            system=system_image_path,
229*800a58d9SAndroid Build Coastguard Worker            system_dlkm=system_dlkm_image_path))
230*800a58d9SAndroid Build Coastguard Worker
231*800a58d9SAndroid Build Coastguard Worker    # Create the vbmeta image.
232*800a58d9SAndroid Build Coastguard Worker    vbmeta_image_path = os.path.join(output_dir, "disabled_vbmeta.img")
233*800a58d9SAndroid Build Coastguard Worker    ota.MakeDisabledVbmetaImage(vbmeta_image_path)
234*800a58d9SAndroid Build Coastguard Worker
235*800a58d9SAndroid Build Coastguard Worker    # Create the disk image.
236*800a58d9SAndroid Build Coastguard Worker    disk_image = os.path.join(output_dir, "mixed_disk.img")
237*800a58d9SAndroid Build Coastguard Worker    ota.MkCombinedImg(
238*800a58d9SAndroid Build Coastguard Worker        disk_image,
239*800a58d9SAndroid Build Coastguard Worker        _FindFileByNames(image_dir, [_SYSTEM_QEMU_CONFIG_FILE_NAME]),
240*800a58d9SAndroid Build Coastguard Worker        lambda partition: ota_tools.GetImageForPartition(
241*800a58d9SAndroid Build Coastguard Worker            partition, image_dir, super=mixed_super_image_path,
242*800a58d9SAndroid Build Coastguard Worker            vbmeta=vbmeta_image_path))
243*800a58d9SAndroid Build Coastguard Worker    return disk_image
244*800a58d9SAndroid Build Coastguard Worker
245*800a58d9SAndroid Build Coastguard Worker
246*800a58d9SAndroid Build Coastguard Workerdef FormatRemoteHostInstanceName(hostname, console_port, build_info):
247*800a58d9SAndroid Build Coastguard Worker    """Convert address and build info to a remote host instance name.
248*800a58d9SAndroid Build Coastguard Worker
249*800a58d9SAndroid Build Coastguard Worker    Args:
250*800a58d9SAndroid Build Coastguard Worker        hostname: A string, the IPv4 address or domain name of the host.
251*800a58d9SAndroid Build Coastguard Worker        console_port: An integer, the emulator console port.
252*800a58d9SAndroid Build Coastguard Worker        build_info: A dict containing the build ID and target.
253*800a58d9SAndroid Build Coastguard Worker
254*800a58d9SAndroid Build Coastguard Worker    Returns:
255*800a58d9SAndroid Build Coastguard Worker        A string, the instance name.
256*800a58d9SAndroid Build Coastguard Worker    """
257*800a58d9SAndroid Build Coastguard Worker    build_id = build_info.get(constants.BUILD_ID)
258*800a58d9SAndroid Build Coastguard Worker    build_target = build_info.get(constants.BUILD_TARGET)
259*800a58d9SAndroid Build Coastguard Worker    build_info_str = (f"{build_id}-{build_target}" if
260*800a58d9SAndroid Build Coastguard Worker                      build_id and build_target else
261*800a58d9SAndroid Build Coastguard Worker                      "userbuild")
262*800a58d9SAndroid Build Coastguard Worker    return _REMOTE_HOST_INSTANCE_NAME_FORMAT % {
263*800a58d9SAndroid Build Coastguard Worker        "hostname": hostname.replace("-", "_"),
264*800a58d9SAndroid Build Coastguard Worker        "console_port": console_port,
265*800a58d9SAndroid Build Coastguard Worker        "build_info": build_info_str,
266*800a58d9SAndroid Build Coastguard Worker    }
267*800a58d9SAndroid Build Coastguard Worker
268*800a58d9SAndroid Build Coastguard Worker
269*800a58d9SAndroid Build Coastguard Workerdef ParseRemoteHostConsoleAddress(instance_name):
270*800a58d9SAndroid Build Coastguard Worker    """Parse emulator console address from a remote host instance name.
271*800a58d9SAndroid Build Coastguard Worker
272*800a58d9SAndroid Build Coastguard Worker    Args:
273*800a58d9SAndroid Build Coastguard Worker        instance_name: A string, the instance name.
274*800a58d9SAndroid Build Coastguard Worker
275*800a58d9SAndroid Build Coastguard Worker    Returns:
276*800a58d9SAndroid Build Coastguard Worker        The hostname as a string and the console port as an integer.
277*800a58d9SAndroid Build Coastguard Worker        None if the name does not represent a goldfish instance on remote host.
278*800a58d9SAndroid Build Coastguard Worker    """
279*800a58d9SAndroid Build Coastguard Worker    match = _REMOTE_HOST_INSTANCE_NAME_PATTERN.fullmatch(instance_name)
280*800a58d9SAndroid Build Coastguard Worker    return ((match.group("hostname").replace("_", "-"),
281*800a58d9SAndroid Build Coastguard Worker             int(match.group("console_port")))
282*800a58d9SAndroid Build Coastguard Worker            if match else None)
283*800a58d9SAndroid Build Coastguard Worker
284*800a58d9SAndroid Build Coastguard Worker
285*800a58d9SAndroid Build Coastguard Workerdef ConvertAvdSpecToArgs(avd_spec):
286*800a58d9SAndroid Build Coastguard Worker    """Convert hardware specification to emulator arguments.
287*800a58d9SAndroid Build Coastguard Worker
288*800a58d9SAndroid Build Coastguard Worker    Args:
289*800a58d9SAndroid Build Coastguard Worker        avd_spec: The AvdSpec object.
290*800a58d9SAndroid Build Coastguard Worker
291*800a58d9SAndroid Build Coastguard Worker    Returns:
292*800a58d9SAndroid Build Coastguard Worker        A list of strings, the arguments.
293*800a58d9SAndroid Build Coastguard Worker    """
294*800a58d9SAndroid Build Coastguard Worker    args = []
295*800a58d9SAndroid Build Coastguard Worker    if avd_spec.gpu:
296*800a58d9SAndroid Build Coastguard Worker        args.extend(("-gpu", avd_spec.gpu))
297*800a58d9SAndroid Build Coastguard Worker
298*800a58d9SAndroid Build Coastguard Worker    if not avd_spec.hw_customize:
299*800a58d9SAndroid Build Coastguard Worker        return args
300*800a58d9SAndroid Build Coastguard Worker
301*800a58d9SAndroid Build Coastguard Worker    cores = avd_spec.hw_property.get(constants.HW_ALIAS_CPUS)
302*800a58d9SAndroid Build Coastguard Worker    if cores:
303*800a58d9SAndroid Build Coastguard Worker        args.extend(("-cores", cores))
304*800a58d9SAndroid Build Coastguard Worker    x_res = avd_spec.hw_property.get(constants.HW_X_RES)
305*800a58d9SAndroid Build Coastguard Worker    y_res = avd_spec.hw_property.get(constants.HW_Y_RES)
306*800a58d9SAndroid Build Coastguard Worker    if x_res and y_res:
307*800a58d9SAndroid Build Coastguard Worker        args.extend(("-skin", ("%sx%s" % (x_res, y_res))))
308*800a58d9SAndroid Build Coastguard Worker    dpi = avd_spec.hw_property.get(constants.HW_ALIAS_DPI)
309*800a58d9SAndroid Build Coastguard Worker    if dpi:
310*800a58d9SAndroid Build Coastguard Worker        args.extend(("-dpi-device", dpi))
311*800a58d9SAndroid Build Coastguard Worker    memory_size_mb = avd_spec.hw_property.get(constants.HW_ALIAS_MEMORY)
312*800a58d9SAndroid Build Coastguard Worker    if memory_size_mb:
313*800a58d9SAndroid Build Coastguard Worker        args.extend(("-memory", memory_size_mb))
314*800a58d9SAndroid Build Coastguard Worker    userdata_size_mb = avd_spec.hw_property.get(constants.HW_ALIAS_DISK)
315*800a58d9SAndroid Build Coastguard Worker    if userdata_size_mb:
316*800a58d9SAndroid Build Coastguard Worker        args.extend(("-partition-size", userdata_size_mb))
317*800a58d9SAndroid Build Coastguard Worker
318*800a58d9SAndroid Build Coastguard Worker    return args
319