xref: /aosp_15_r20/external/autotest/client/common_lib/android_utils.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Copyright 2016 The Chromium Authors. All rights reserved.
2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be
3*9c5db199SXin Li# found in the LICENSE file.
4*9c5db199SXin Li
5*9c5db199SXin Li"""
6*9c5db199SXin LiThis module provides utilities needed to provision and run test on Android
7*9c5db199SXin Lidevices.
8*9c5db199SXin Li"""
9*9c5db199SXin Li
10*9c5db199SXin Li
11*9c5db199SXin Liimport logging
12*9c5db199SXin Liimport re
13*9c5db199SXin Li
14*9c5db199SXin Liimport common
15*9c5db199SXin Lifrom autotest_lib.client.common_lib import global_config
16*9c5db199SXin Li
17*9c5db199SXin Li
18*9c5db199SXin LiCONFIG = global_config.global_config
19*9c5db199SXin Li
20*9c5db199SXin Lidef get_config_value_regex(section, regex):
21*9c5db199SXin Li    """Get config values from global config based on regex of the key.
22*9c5db199SXin Li
23*9c5db199SXin Li    @param section: Section of the config, e.g., CLIENT.
24*9c5db199SXin Li    @param regex: Regular expression of the key pattern.
25*9c5db199SXin Li
26*9c5db199SXin Li    @return: A dictionary of all config values matching the regex. Value is
27*9c5db199SXin Li             assumed to be comma separated, and is converted to a list.
28*9c5db199SXin Li    """
29*9c5db199SXin Li    configs = CONFIG.get_config_value_regex(section, regex)
30*9c5db199SXin Li    result = {}
31*9c5db199SXin Li    for key, value in configs.items():
32*9c5db199SXin Li        match = re.match(regex, key)
33*9c5db199SXin Li        result[match.group(1)] = [v.strip() for v in value.split(',')
34*9c5db199SXin Li                                  if v.strip()]
35*9c5db199SXin Li    return result
36*9c5db199SXin Li
37*9c5db199SXin Li
38*9c5db199SXin Liclass AndroidAliases(object):
39*9c5db199SXin Li    """Wrapper class for getting alias names for an android device.
40*9c5db199SXin Li
41*9c5db199SXin Li    On android it is only possible to get a devices product name
42*9c5db199SXin Li    (eg. marlin, sailfish). However a product may have several aliases
43*9c5db199SXin Li    that it is called by such as the name of its board, or a public name,
44*9c5db199SXin Li    etc. This wrapper allows for mapping the product name to different
45*9c5db199SXin Li    aliases.
46*9c5db199SXin Li
47*9c5db199SXin Li    Terms:
48*9c5db199SXin Li        product: The name a device reports itself as.
49*9c5db199SXin Li        board: The name of the hardware board in a device.
50*9c5db199SXin Li        alias: Some name a device is called, this includes both product and
51*9c5db199SXin Li               board.
52*9c5db199SXin Li    """
53*9c5db199SXin Li
54*9c5db199SXin Li    # regex pattern for CLIENT/android_board_name[product]. For example,
55*9c5db199SXin Li    # global config can have following config in CLIENT section to indicate that
56*9c5db199SXin Li    # android product `zzz` has following board name.
57*9c5db199SXin Li    # xyz.
58*9c5db199SXin Li    # android_board_name_zzz: xyz
59*9c5db199SXin Li    BOARD_NAME_PATTERN = 'android_board_name_(.*)'
60*9c5db199SXin Li
61*9c5db199SXin Li
62*9c5db199SXin Li    # A dict of product:board for product board names, can be defined in global
63*9c5db199SXin Li    # config CLIENT/android_board_name_[product]
64*9c5db199SXin Li    board_name_map = get_config_value_regex('CLIENT', BOARD_NAME_PATTERN)
65*9c5db199SXin Li
66*9c5db199SXin Li    @classmethod
67*9c5db199SXin Li    def get_board_name(cls, product):
68*9c5db199SXin Li        """Get the board name of a product.
69*9c5db199SXin Li
70*9c5db199SXin Li        The board name of an android device is what the hardware is named.
71*9c5db199SXin Li        In many cases this is the same name as the reported product name,
72*9c5db199SXin Li        however some devices have boards that differ from the product name.
73*9c5db199SXin Li
74*9c5db199SXin Li        @param product: The name of the product.
75*9c5db199SXin Li        @returns: The board name of the given product.
76*9c5db199SXin Li        """
77*9c5db199SXin Li        boards = cls.board_name_map.get(product, None)
78*9c5db199SXin Li        if boards:
79*9c5db199SXin Li            return boards[0]
80*9c5db199SXin Li        return product
81*9c5db199SXin Li
82*9c5db199SXin Li
83*9c5db199SXin Liclass AndroidArtifacts(object):
84*9c5db199SXin Li    """A wrapper class for constants and methods related to artifacts.
85*9c5db199SXin Li    """
86*9c5db199SXin Li
87*9c5db199SXin Li    BOOTLOADER_IMAGE = 'bootloader_image'
88*9c5db199SXin Li    DTB = 'dtb'
89*9c5db199SXin Li    RADIO_IMAGE = 'radio_image'
90*9c5db199SXin Li    TARGET_FILES = 'target_files'
91*9c5db199SXin Li    VENDOR_PARTITIONS = 'vendor_partitions'
92*9c5db199SXin Li    ZIP_IMAGE = 'zip_images'
93*9c5db199SXin Li
94*9c5db199SXin Li    # (os, board) = 'artifacts'
95*9c5db199SXin Li    DEFAULT_ARTIFACTS_MAP = {
96*9c5db199SXin Li        ('android', 'default'): [BOOTLOADER_IMAGE, RADIO_IMAGE, ZIP_IMAGE],
97*9c5db199SXin Li        ('brillo', 'default'):  [ZIP_IMAGE, VENDOR_PARTITIONS],
98*9c5db199SXin Li        ('emulated_brillo', 'default'): [TARGET_FILES, DTB],
99*9c5db199SXin Li    }
100*9c5db199SXin Li
101*9c5db199SXin Li    # Default artifacts for Android provision
102*9c5db199SXin Li    DEFAULT_ARTIFACTS_TO_BE_STAGED_FOR_IMAGE = (
103*9c5db199SXin Li            ','.join([BOOTLOADER_IMAGE, RADIO_IMAGE, ZIP_IMAGE]))
104*9c5db199SXin Li
105*9c5db199SXin Li    # regex pattern for CLIENT/android_artifacts_[board]. For example, global
106*9c5db199SXin Li    # config can have following config in CLIENT section to indicate that
107*9c5db199SXin Li    # android board `xyz` needs to stage artifacts
108*9c5db199SXin Li    # ['bootloader_image', 'radio_image'] for provision.
109*9c5db199SXin Li    # android_artifacts_xyz: bootloader_image,radio_image
110*9c5db199SXin Li    ARTIFACTS_LIST_PATTERN = 'android_artifacts_(.*)'
111*9c5db199SXin Li
112*9c5db199SXin Li    # A dict of board:artifacts, can be defined in global config
113*9c5db199SXin Li    # CLIENT/android_artifacts_[board]
114*9c5db199SXin Li    artifacts_map = get_config_value_regex('CLIENT', ARTIFACTS_LIST_PATTERN)
115*9c5db199SXin Li
116*9c5db199SXin Li    @classmethod
117*9c5db199SXin Li    def get_artifacts_for_reimage(cls, board, os='android'):
118*9c5db199SXin Li        """Get artifacts need to be staged for reimage for given board.
119*9c5db199SXin Li
120*9c5db199SXin Li        @param board: Name of the board.
121*9c5db199SXin Li
122*9c5db199SXin Li        @return: A string of artifacts to be staged.
123*9c5db199SXin Li        """
124*9c5db199SXin Li        logging.debug('artifacts for %s %s', os, board)
125*9c5db199SXin Li        if board in cls.artifacts_map:
126*9c5db199SXin Li            logging.debug('Found override of artifacts for board %s: %s', board,
127*9c5db199SXin Li                          cls.artifacts_map[board])
128*9c5db199SXin Li            artifacts = cls.artifacts_map[board]
129*9c5db199SXin Li        elif (os, board) in cls.DEFAULT_ARTIFACTS_MAP:
130*9c5db199SXin Li            artifacts = cls.DEFAULT_ARTIFACTS_MAP[(os, board)]
131*9c5db199SXin Li        else:
132*9c5db199SXin Li            artifacts = cls.DEFAULT_ARTIFACTS_MAP[(os, 'default')]
133*9c5db199SXin Li        logging.debug('found %s', ','.join(artifacts))
134*9c5db199SXin Li        return ','.join(artifacts)
135