• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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