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""" 6This module provides utilities needed to provision and run test on Android 7devices. 8""" 9 10 11import logging 12import re 13 14import common 15from autotest_lib.client.common_lib import global_config 16 17 18CONFIG = global_config.global_config 19 20def 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 38class 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 83class 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