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