• 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
26from hb_internal.preloader.parse_vendor_product_config import get_vendor_parts_list
27
28class Product():
29    @staticmethod
30    def get_products():
31        config = Config()
32        # ext products configuration
33        _ext_scan_path = os.path.join(config.root_path,
34                                      'out/products_ext/vendor')
35        if os.path.exists(_ext_scan_path):
36            for company in os.listdir(_ext_scan_path):
37                company_path = os.path.join(_ext_scan_path, company)
38                if not os.path.isdir(company_path):
39                    continue
40
41                for product in os.listdir(company_path):
42                    p_config_path = os.path.join(company_path, product)
43                    config_path = os.path.join(p_config_path, 'config.json')
44
45                    if os.path.isfile(config_path):
46                        info = read_json_file(config_path)
47                        product_name = info.get('product_name')
48                        if info.get('product_path'):
49                            product_path = os.path.join(
50                                config.root_path, info.get('product_path'))
51                        else:
52                            product_path = p_config_path
53                        if product_name is not None:
54                            yield {
55                                'company': company,
56                                "name": product_name,
57                                'product_config_path': p_config_path,
58                                'product_path': product_path,
59                                'version': info.get('version', '3.0'),
60                                'os_level': info.get('type', "mini"),
61                                'build_out_path': info.get('build_out_path'),
62                                'subsystem_config_json':
63                                info.get('subsystem_config_json'),
64                                'config': config_path,
65                                'component_type': info.get('component_type', '')
66                            }
67        for company in os.listdir(config.vendor_path):
68            company_path = os.path.join(config.vendor_path, company)
69            if not os.path.isdir(company_path):
70                continue
71
72            for product in os.listdir(company_path):
73                product_path = os.path.join(company_path, product)
74                config_path = os.path.join(product_path, 'config.json')
75
76                if os.path.isfile(config_path):
77                    info = read_json_file(config_path)
78                    product_name = info.get('product_name')
79                    if product_name is not None:
80                        yield {
81                            'company': company,
82                            "name": product_name,
83                            'product_config_path': product_path,
84                            'product_path': product_path,
85                            'version': info.get('version', '3.0'),
86                            'os_level': info.get('type', "mini"),
87                            'config': config_path,
88                            'component_type': info.get('component_type', '')
89                        }
90        bip_path = config.built_in_product_path
91        for item in os.listdir(bip_path):
92            if item[0] in ".":
93                continue
94            else:
95                product_name = item[0:-len('.json')] if item.endswith('.json') else item
96                config_path = os.path.join(bip_path, item)
97                info = read_json_file(config_path)
98                yield {
99                    'company': 'built-in',
100                    "name": product_name,
101                    'product_config_path': bip_path,
102                    'product_path': bip_path,
103                    'version': info.get('version', '2.0'),
104                    'os_level': info.get('type', 'standard'),
105                    'config': config_path,
106                    'component_type': info.get('component_type', '')
107                }
108
109    @staticmethod
110    def get_device_info(product_json):
111        info = read_json_file(product_json)
112        config = Config()
113        version = info.get('version', '3.0')
114
115        if version == '2.0':
116            device_json = os.path.join(config.built_in_device_path,
117                                       f'{info["product_device"]}.json')
118            device_info = read_json_file(device_json)
119            return {
120                'board': device_info.get('device_name'),
121                'kernel': device_info.get('kernel_type', 'linux'),
122                'kernel_version': device_info.get('kernel_version'),
123                'company': device_info.get('device_company'),
124                'board_path': device_info.get('device_build_path'),
125                'target_cpu': device_info.get('target_cpu'),
126                'target_os': device_info.get('target_os')
127            }
128        elif version == '3.0':
129            device_company = info.get('device_company')
130            board = info.get('board')
131            _board_path = info.get('board_path')
132            if _board_path and os.path.exists(
133                    os.path.join(config.root_path, _board_path)):
134                board_path = os.path.join(config.root_path, _board_path)
135            else:
136                board_path = os.path.join(config.root_path, 'device',
137                                          device_company, board)
138                # board and soc decoupling feature will add boards
139                # directory path here.
140                if not os.path.exists(board_path):
141                    board_path = os.path.join(config.root_path, 'device',
142                                              'board', device_company, board)
143            board_config_path = None
144            if info.get('board_config_path'):
145                board_config_path = os.path.join(config.root_path,
146                                                 info.get('board_config_path'))
147
148            return {
149                'board': info.get('board'),
150                'kernel': info.get('kernel_type'),
151                'kernel_version': info.get('kernel_version'),
152                'company': info.get('device_company'),
153                'board_path': board_path,
154                'board_config_path': board_config_path,
155                'target_cpu': info.get('target_cpu'),
156                'target_os': info.get('target_os')
157            }
158        else:
159            raise OHOSException(f'wrong version number in {product_json}')
160
161    @staticmethod
162    def get_features(product_json):
163        if not os.path.isfile(product_json):
164            raise OHOSException(f'features {product_json} not found')
165
166        config = Config()
167        # Get all inherit files
168        files = [os.path.join(config.root_path, file) for file in read_json_file(product_json).get('inherit', [])]
169        # Add the product config file to last with highest priority
170        files.append(product_json)
171
172        # Read all parts in order
173        all_parts = {}
174        for _file in files:
175            if not os.path.isfile(_file):
176                continue
177            _info = read_json_file(_file)
178            parts = _info.get('parts')
179            if parts:
180                all_parts.update(parts)
181            else:
182                # v3 config files
183                all_parts.update(get_vendor_parts_list(_info))
184
185        # Get all features
186        features_list = []
187        for part, val in all_parts.items():
188            if "features" not in val:
189                continue
190            for key, val in val["features"].items():
191                _item = ''
192                if isinstance(val, bool):
193                    _item = f'{key}={str(val).lower()}'
194                elif isinstance(val, int):
195                    _item = f'{key}={val}'
196                elif isinstance(val, str):
197                    _item = f'{key}="{val}"'
198                else:
199                    raise Exception(
200                        "part feature '{key}:{val}' type not support.")
201                features_list.append(_item)
202        return features_list
203
204    @staticmethod
205    def get_components(product_json, subsystems):
206        if not os.path.isfile(product_json):
207            raise OHOSException(f'{product_json} not found')
208
209        components_dict = defaultdict(list)
210        product_data = read_json_file(product_json)
211        for subsystem in product_data.get('subsystems', []):
212            sname = subsystem.get('subsystem', '')
213            if not len(subsystems) or sname in subsystems:
214                components_dict[sname] += [
215                    comp['component']
216                    for comp in subsystem.get('components', [])
217                ]
218
219        return components_dict, product_data.get('board', ''),\
220            product_data.get('kernel_type', '')
221
222    @staticmethod
223    def get_product_info(product_name, company=None):
224        for product_info in Product.get_products():
225            cur_company = product_info['company']
226            cur_product = product_info['name']
227            if company:
228                if cur_company == company and cur_product == product_name:
229                    return product_info
230            else:
231                if cur_product == product_name:
232                    return product_info
233
234        raise OHOSException(f'product {product_name}@{company} not found')
235
236    @staticmethod
237    def product_menuconfig():
238        product_path_dict = {}
239        company_separator = None
240        for product_info in Product.get_products():
241            company = product_info['company']
242            product = product_info['name']
243            if company_separator is None or company_separator != company:
244                company_separator = company
245                product_key = Separator(company_separator)
246                product_path_dict[product_key] = None
247
248            product_path_dict['{}@{}'.format(product, company)] = product_info
249
250        if not len(product_path_dict):
251            raise OHOSException('no valid product found')
252
253        choices = [
254            product if isinstance(product, Separator) else {
255                'name': product.split('@')[0],
256                'value': product.split('@')[1]
257            } for product in product_path_dict.keys()
258        ]
259        menu = Menuconfig()
260        product = menu.list_promt('product', 'Which product do you need?',
261                                  choices).get('product')
262        product_key = f'{product[0]}@{product[1]}'
263        return product_path_dict[product_key]
264