1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2020 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18import os 19from collections import defaultdict 20 21from hb_internal.common.utils import read_json_file 22from hb_internal.common.utils import OHOSException 23from hb_internal.common.config import Config 24from hb_internal.cts.menuconfig import Menuconfig 25from hb_internal.cts.common import Separator 26 27 28class Product(): 29 @staticmethod 30 def get_products(): 31 config = Config() 32 for company in os.listdir(config.vendor_path): 33 company_path = os.path.join(config.vendor_path, company) 34 if not os.path.isdir(company_path): 35 continue 36 37 for product in os.listdir(company_path): 38 product_path = os.path.join(company_path, product) 39 config_path = os.path.join(product_path, 'config.json') 40 41 if os.path.isfile(config_path): 42 info = read_json_file(config_path) 43 product_name = info.get('product_name') 44 if product_name is not None: 45 yield { 46 'company': company, 47 "name": product_name, 48 'path': product_path, 49 'version': info.get('version', '3.0'), 50 'os_level': info.get('type', "mini"), 51 'config': config_path 52 } 53 bip_path = config.built_in_product_path 54 for item in os.listdir(bip_path): 55 product_name = item[0:-len('.json')] if item.endswith('.json') else item 56 config_path = os.path.join(bip_path, item) 57 info = read_json_file(config_path) 58 yield { 59 'company': 'built-in', 60 "name": product_name, 61 'path': bip_path, 62 'version': info.get('version', '2.0'), 63 'os_level': info.get('type', 'standard'), 64 'config': config_path 65 } 66 67 @staticmethod 68 def get_device_info(product_json): 69 info = read_json_file(product_json) 70 config = Config() 71 version = info.get('version', '3.0') 72 73 if version == '2.0': 74 device_json = os.path.join(config.built_in_device_path, 75 f'{info["product_device"]}.json') 76 device_info = read_json_file(device_json) 77 return { 78 'board': device_info.get('device_name'), 79 'kernel': device_info.get('kernel_type', 'linux'), 80 'kernel_version': device_info.get('kernel_version'), 81 'company': device_info.get('device_company'), 82 'board_path': device_info.get('device_build_path'), 83 'target_cpu': device_info.get('target_cpu'), 84 'target_os': device_info.get('target_os') 85 } 86 elif version == '3.0': 87 device_company = info.get('device_company') 88 board = info.get('board') 89 board_path = os.path.join(config.root_path, 'device', 90 device_company, board) 91 # board and soc decoupling feature will add boards directory path here. 92 if not os.path.exists(board_path): 93 board_path = os.path.join(config.root_path, 'device', 'board', 94 device_company, board) 95 96 return { 97 'board': info.get('board'), 98 'kernel': info.get('kernel_type'), 99 'kernel_version': info.get('kernel_version'), 100 'company': info.get('device_company'), 101 'board_path': board_path, 102 'target_cpu': info.get('target_cpu'), 103 'target_os': info.get('target_os') 104 } 105 else: 106 raise OHOSException(f'wrong version number in {product_json}') 107 108 @staticmethod 109 def get_features(product_json): 110 if not os.path.isfile(product_json): 111 raise OHOSException(f'features {product_json} not found') 112 113 features_list = [] 114 config = Config() 115 if config.version == '3.0': 116 subsystems = read_json_file(product_json).get('subsystems', []) 117 for subsystem in subsystems: 118 for component in subsystem.get('components', []): 119 features = component.get('features', []) 120 features_list += [ 121 feature for feature in features if len(feature) 122 ] 123 elif config.version == '2.0': 124 features = read_json_file(product_json).get('parts', {}).values() 125 for feature in features: 126 if feature.get('features'): 127 features_kv = feature.get('features') 128 for key, val in features_kv.items(): 129 _item = '' 130 if isinstance(val, bool): 131 _item = f'{key}={str(val).lower()}' 132 elif isinstance(val, int): 133 _item = f'{key}={val}' 134 elif isinstance(val, str): 135 _item = f'{key}="{val}"' 136 else: 137 raise Exception( 138 "part feature '{key}:{val}' type not support.") 139 features_list.append(_item) 140 141 return features_list 142 143 @staticmethod 144 def get_components(product_json, subsystems): 145 if not os.path.isfile(product_json): 146 raise OHOSException(f'{product_json} not found') 147 148 components_dict = defaultdict(list) 149 product_data = read_json_file(product_json) 150 for subsystem in product_data.get('subsystems', []): 151 sname = subsystem.get('subsystem', '') 152 if not len(subsystems) or sname in subsystems: 153 components_dict[sname] += [ 154 comp['component'] 155 for comp in subsystem.get('components', []) 156 ] 157 158 return components_dict, product_data.get('board', ''),\ 159 product_data.get('kernel_type', '') 160 161 @staticmethod 162 def get_product_info(product_name, company=None): 163 for product_info in Product.get_products(): 164 cur_company = product_info['company'] 165 cur_product = product_info['name'] 166 if company: 167 if cur_company == company and cur_product == product_name: 168 return product_info 169 else: 170 if cur_product == product_name: 171 return product_info 172 173 raise OHOSException(f'product {product_name}@{company} not found') 174 175 @staticmethod 176 def product_menuconfig(): 177 product_path_dict = {} 178 company_separator = None 179 for product_info in Product.get_products(): 180 company = product_info['company'] 181 product = product_info['name'] 182 if company_separator is None or company_separator != company: 183 company_separator = company 184 product_key = Separator(company_separator) 185 product_path_dict[product_key] = None 186 187 product_path_dict['{}@{}'.format(product, company)] = product_info 188 189 if not len(product_path_dict): 190 raise OHOSException('no valid product found') 191 192 choices = [ 193 product if isinstance(product, Separator) else { 194 'name': product.split('@')[0], 195 'value': product.split('@')[1] 196 } for product in product_path_dict.keys() 197 ] 198 menu = Menuconfig() 199 product = menu.list_promt('product', 'Which product do you need?', 200 choices).get('product') 201 product_key = f'{product[0]}@{product[1]}' 202 return product_path_dict[product_key] 203