15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci"""
45f9996aaSopenharmony_ciCopyright 2023 Huawei Device Co., Ltd.
55f9996aaSopenharmony_ciLicensed under the Apache License, Version 2.0 (the "License");
65f9996aaSopenharmony_ciyou may not use this file except in compliance with the License.
75f9996aaSopenharmony_ciYou may obtain a copy of the License at
85f9996aaSopenharmony_ci
95f9996aaSopenharmony_ci    http://www.apache.org/licenses/LICENSE-2.0
105f9996aaSopenharmony_ci
115f9996aaSopenharmony_ciUnless required by applicable law or agreed to in writing, software
125f9996aaSopenharmony_cidistributed under the License is distributed on an "AS IS" BASIS,
135f9996aaSopenharmony_ciWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145f9996aaSopenharmony_ciSee the License for the specific language governing permissions and
155f9996aaSopenharmony_cilimitations under the License.
165f9996aaSopenharmony_ci
175f9996aaSopenharmony_ci"""
185f9996aaSopenharmony_ci
195f9996aaSopenharmony_ciimport os
205f9996aaSopenharmony_ciimport re
215f9996aaSopenharmony_ciimport json
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_cifrom util.log_util import LogUtil
245f9996aaSopenharmony_cifrom resources.config import Config
255f9996aaSopenharmony_ci
265f9996aaSopenharmony_cibudle_json_files = []
275f9996aaSopenharmony_cistandard_part_roms = []
285f9996aaSopenharmony_cipart_info_list = []
295f9996aaSopenharmony_ci
305f9996aaSopenharmony_ci
315f9996aaSopenharmony_cidef part_size_compare(module_info_list, part_name, part_size):
325f9996aaSopenharmony_ci    for standard_part in standard_part_roms:
335f9996aaSopenharmony_ci        if standard_part['part_name'] == part_name and standard_part['part_size'] != 'None':
345f9996aaSopenharmony_ci            sta_size = re.findall(r"\d+", standard_part['part_size'])
355f9996aaSopenharmony_ci            rea_size = re.findall(r"\d+", part_size)
365f9996aaSopenharmony_ci            if int(sta_size[0]) >= int(rea_size[0]):
375f9996aaSopenharmony_ci                conform_str = ''.join(['part_name: {}'.format(part_name).ljust(55), \
385f9996aaSopenharmony_ci                              'actual_size: {}'.format(part_size).ljust(25), \
395f9996aaSopenharmony_ci                              'standard_size: {}'.format(standard_part['part_size']).ljust(25), \
405f9996aaSopenharmony_ci                               'conform to the rules'])
415f9996aaSopenharmony_ci                LogUtil.hb_info(conform_str)
425f9996aaSopenharmony_ci                part_info_dict = {}
435f9996aaSopenharmony_ci                part_info_dict["part_name"] = part_name
445f9996aaSopenharmony_ci                part_info_dict["actual_size"] = part_size
455f9996aaSopenharmony_ci                part_info_dict["standard_size"] = standard_part['part_size']
465f9996aaSopenharmony_ci                part_info_dict["status_info"] = "'rom' conform to the rules"
475f9996aaSopenharmony_ci                part_info_dict["modules_info"] = module_info_list
485f9996aaSopenharmony_ci                part_info_list.append(part_info_dict)
495f9996aaSopenharmony_ci
505f9996aaSopenharmony_ci            elif int(sta_size[0]) < int(rea_size[0]):
515f9996aaSopenharmony_ci                out_of_standard_str = ''.join(['part_name: {}'.format(part_name).ljust(55), \
525f9996aaSopenharmony_ci                                      'actual_size: {}'.format(part_size).ljust(25), \
535f9996aaSopenharmony_ci                                      'standard_size: {}'.format(standard_part['part_size']).ljust(25), \
545f9996aaSopenharmony_ci                                       'rom out of standard'])
555f9996aaSopenharmony_ci                LogUtil.hb_info(out_of_standard_str)
565f9996aaSopenharmony_ci                part_info_dict = {}
575f9996aaSopenharmony_ci                part_info_dict["part_name"] = part_name
585f9996aaSopenharmony_ci                part_info_dict["actual_size"] = part_size
595f9996aaSopenharmony_ci                part_info_dict["standard_size"] = standard_part['part_size']
605f9996aaSopenharmony_ci                part_info_dict["status_info"] = "'rom' out of standard"
615f9996aaSopenharmony_ci                part_info_dict["modules_info"] = module_info_list
625f9996aaSopenharmony_ci                part_info_list.append(part_info_dict)
635f9996aaSopenharmony_ci        else:
645f9996aaSopenharmony_ci            if standard_part['part_name'] == part_name and standard_part['part_size'] == 'None':
655f9996aaSopenharmony_ci                not_yet_standard_str = ('part_name: {}'.format(part_name)).ljust(55) + \
665f9996aaSopenharmony_ci                                       ('actual_size: {}'.format(part_size)).ljust(50) + \
675f9996aaSopenharmony_ci                                        "This part does not set standard 'rom' size".ljust(25)
685f9996aaSopenharmony_ci                LogUtil.hb_info(not_yet_standard_str)
695f9996aaSopenharmony_ci                part_info_dict = {}
705f9996aaSopenharmony_ci                part_info_dict["part_name"] = part_name
715f9996aaSopenharmony_ci                part_info_dict["actual_size"] = part_size
725f9996aaSopenharmony_ci                part_info_dict["standard_size"] = standard_part['part_size']
735f9996aaSopenharmony_ci                part_info_dict["status_info"] = "This part does not set standard 'rom' size"
745f9996aaSopenharmony_ci                part_info_dict["modules_info"] = module_info_list
755f9996aaSopenharmony_ci                part_info_list.append(part_info_dict)
765f9996aaSopenharmony_ci
775f9996aaSopenharmony_ci
785f9996aaSopenharmony_cidef collect_part_name(root_path):
795f9996aaSopenharmony_ci    install_parts = []
805f9996aaSopenharmony_ci    file_path = os.path.join(root_path, "packages/phone/system_install_parts.json")
815f9996aaSopenharmony_ci    if os.path.isfile(file_path):
825f9996aaSopenharmony_ci        with open(file_path, 'rb') as file:
835f9996aaSopenharmony_ci            file_json = json.load(file)
845f9996aaSopenharmony_ci            for part_info in file_json:
855f9996aaSopenharmony_ci                part_info_dict = {}
865f9996aaSopenharmony_ci                part_info_dict["part_name"] = part_info["part_name"]
875f9996aaSopenharmony_ci                part_info_dict["part_info_file"] = part_info["part_info_file"]
885f9996aaSopenharmony_ci                install_parts.append(part_info_dict)
895f9996aaSopenharmony_ci    return install_parts
905f9996aaSopenharmony_ci
915f9996aaSopenharmony_ci
925f9996aaSopenharmony_cidef colletct_modules_json_path(out_path, install_parts):
935f9996aaSopenharmony_ci    module_info_list = []
945f9996aaSopenharmony_ci    for part_info_dict in install_parts:
955f9996aaSopenharmony_ci        part_info_path = os.path.join(out_path, part_info_dict["part_info_file"])
965f9996aaSopenharmony_ci        if os.path.isfile(part_info_path):
975f9996aaSopenharmony_ci            with open(part_info_path, 'rb') as file:
985f9996aaSopenharmony_ci                file_json = json.load(file)
995f9996aaSopenharmony_ci                for module_info in file_json:
1005f9996aaSopenharmony_ci                    if module_info["part_name"] == part_info_dict["part_name"]:
1015f9996aaSopenharmony_ci                        module_json_path = {}
1025f9996aaSopenharmony_ci                        module_json_path["module_info_path"] = module_info["module_info_file"]
1035f9996aaSopenharmony_ci                        module_json_path["part_name"] = module_info["part_name"]
1045f9996aaSopenharmony_ci                        module_info_list.append(module_json_path)
1055f9996aaSopenharmony_ci    return module_info_list
1065f9996aaSopenharmony_ci
1075f9996aaSopenharmony_ci
1085f9996aaSopenharmony_cidef sum_of_statistics(out_path, part_name, module_info_list):
1095f9996aaSopenharmony_ci    part_so_size = 0
1105f9996aaSopenharmony_ci    module_list = []
1115f9996aaSopenharmony_ci    for module_info in module_info_list:
1125f9996aaSopenharmony_ci        if part_name == module_info['part_name']:
1135f9996aaSopenharmony_ci            module_info_path = os.path.join(out_path, module_info['module_info_path'])
1145f9996aaSopenharmony_ci            if os.path.isfile(module_info_path):
1155f9996aaSopenharmony_ci                with open(module_info_path, 'rb') as file:
1165f9996aaSopenharmony_ci                    file_json = json.load(file)
1175f9996aaSopenharmony_ci                    so_file_dir = os.path.join(out_path, file_json["source"])
1185f9996aaSopenharmony_ci                    if so_file_dir.endswith(".so") and os.path.isfile(so_file_dir):
1195f9996aaSopenharmony_ci                        module_info_dict = {}
1205f9996aaSopenharmony_ci                        module_info_dict["module_name"] = file_json["label_name"]
1215f9996aaSopenharmony_ci                        module_info_dict["source"] = file_json["source"]
1225f9996aaSopenharmony_ci                        module_info_dict["dest"] = file_json["dest"]
1235f9996aaSopenharmony_ci                        dest_num = len(file_json["dest"])
1245f9996aaSopenharmony_ci                        so_file_size = os.path.getsize(so_file_dir) * dest_num
1255f9996aaSopenharmony_ci                        part_so_size += so_file_size
1265f9996aaSopenharmony_ci                        module_info_dict["module_size"] = f'{round(so_file_size / 1024, 2)}KB'
1275f9996aaSopenharmony_ci                        module_list.append(module_info_dict)
1285f9996aaSopenharmony_ci    return module_list, part_so_size
1295f9996aaSopenharmony_ci
1305f9996aaSopenharmony_ci
1315f9996aaSopenharmony_cidef check_image_size(out_path):
1325f9996aaSopenharmony_ci    image_list = []
1335f9996aaSopenharmony_ci    image_path = os.path.join(out_path, 'packages/phone/images/')
1345f9996aaSopenharmony_ci    if os.path.isdir(image_path):
1355f9996aaSopenharmony_ci        for file in os.listdir(image_path):
1365f9996aaSopenharmony_ci            if file.endswith(".img"):
1375f9996aaSopenharmony_ci                image_dict = {}
1385f9996aaSopenharmony_ci                img_path = os.path.join(image_path, file)
1395f9996aaSopenharmony_ci                image_dict['img_size'] = f'{round(os.path.getsize(img_path) / 1024, 2)}KB'
1405f9996aaSopenharmony_ci                image_dict['img_name'] = file
1415f9996aaSopenharmony_ci                image_list.append(image_dict)
1425f9996aaSopenharmony_ci    return image_list
1435f9996aaSopenharmony_ci
1445f9996aaSopenharmony_ci
1455f9996aaSopenharmony_cidef actual_rom_statistics(out_path):
1465f9996aaSopenharmony_ci    rom_statistics = {}
1475f9996aaSopenharmony_ci    install_parts = collect_part_name(out_path)
1485f9996aaSopenharmony_ci    module_info_list = colletct_modules_json_path(out_path, install_parts)
1495f9996aaSopenharmony_ci    image_list = check_image_size(out_path)
1505f9996aaSopenharmony_ci    rom_statistics["images_info"] = image_list
1515f9996aaSopenharmony_ci
1525f9996aaSopenharmony_ci    for part_info_dict in install_parts:
1535f9996aaSopenharmony_ci        statistics_result = sum_of_statistics(out_path, part_info_dict["part_name"], module_info_list)
1545f9996aaSopenharmony_ci        part_so_size = f'{round(statistics_result[1] / 1024, 2)}KB'
1555f9996aaSopenharmony_ci        part_size_compare(statistics_result[0],
1565f9996aaSopenharmony_ci                            part_info_dict["part_name"],
1575f9996aaSopenharmony_ci                            part_so_size)
1585f9996aaSopenharmony_ci    rom_statistics["parts_info"] = part_info_list
1595f9996aaSopenharmony_ci    json_path = os.path.join(out_path, 'rom_statistics_table.json')
1605f9996aaSopenharmony_ci    json_str = json.dumps(rom_statistics, indent=4)
1615f9996aaSopenharmony_ci    with open(json_path, 'w') as json_file:
1625f9996aaSopenharmony_ci        json_file.write(json_str)
1635f9996aaSopenharmony_ci
1645f9996aaSopenharmony_ci
1655f9996aaSopenharmony_cidef read_bundle_json_file(file_path):
1665f9996aaSopenharmony_ci    with open(file_path, 'rb') as file:
1675f9996aaSopenharmony_ci        file_json = json.load(file)
1685f9996aaSopenharmony_ci        standard_part_rom = {}
1695f9996aaSopenharmony_ci        standard_part_rom["part_name"] = file_json["component"]["name"]
1705f9996aaSopenharmony_ci        if 'rom' not in file_json["component"].keys() or file_json["component"]["rom"] == '':
1715f9996aaSopenharmony_ci            standard_part_rom["part_size"] = 'None'
1725f9996aaSopenharmony_ci        else:
1735f9996aaSopenharmony_ci            standard_part_rom["part_size"] = file_json["component"]["rom"]
1745f9996aaSopenharmony_ci        if standard_part_roms.count(standard_part_rom) == 0:
1755f9996aaSopenharmony_ci            standard_part_roms.append(standard_part_rom)
1765f9996aaSopenharmony_ci
1775f9996aaSopenharmony_ci
1785f9996aaSopenharmony_cidef collect_bundle_json_path(part_root_path):
1795f9996aaSopenharmony_ci    for root, dirs, files in os.walk(part_root_path):
1805f9996aaSopenharmony_ci        abs_path = os.path.abspath(root)
1815f9996aaSopenharmony_ci        for file_name in files:
1825f9996aaSopenharmony_ci            if file_name == 'bundle.json':
1835f9996aaSopenharmony_ci                budle_json_files.append(os.path.join(abs_path, file_name))
1845f9996aaSopenharmony_ci
1855f9996aaSopenharmony_ci
1865f9996aaSopenharmony_cidef read_subsystem_config(root_path):
1875f9996aaSopenharmony_ci    part_json_paths = []
1885f9996aaSopenharmony_ci    part_json_path = os.path.join(root_path, 'build/subsystem_config.json')
1895f9996aaSopenharmony_ci    if os.path.isfile(part_json_path):
1905f9996aaSopenharmony_ci        with open(part_json_path, 'r') as file:
1915f9996aaSopenharmony_ci            file_json = json.load(file)
1925f9996aaSopenharmony_ci            for part_info_valule in file_json.values():
1935f9996aaSopenharmony_ci                for path_k, path_v in part_info_valule.items():
1945f9996aaSopenharmony_ci                    if path_k == "path":
1955f9996aaSopenharmony_ci                        part_json_paths.append(path_v)
1965f9996aaSopenharmony_ci    config = Config()
1975f9996aaSopenharmony_ci    part_json_overlay_path = config.product_path
1985f9996aaSopenharmony_ci    if os.path.isfile(part_json_overlay_path):
1995f9996aaSopenharmony_ci        with open(part_json_overlay_path, 'r') as file:
2005f9996aaSopenharmony_ci            file_json = json.load(file)
2015f9996aaSopenharmony_ci            for part_info_valule in file_json.values():
2025f9996aaSopenharmony_ci                for path_k, path_v in part_info_valule.items():
2035f9996aaSopenharmony_ci                    if path_k == "path":
2045f9996aaSopenharmony_ci                        part_json_paths.append(path_v)
2055f9996aaSopenharmony_ci
2065f9996aaSopenharmony_ci    return part_json_paths
2075f9996aaSopenharmony_ci
2085f9996aaSopenharmony_ci
2095f9996aaSopenharmony_cidef read_ohos_config(root_path):
2105f9996aaSopenharmony_ci    file_path = os.path.join(root_path, "ohos_config.json")
2115f9996aaSopenharmony_ci    with open(file_path, 'r') as file:
2125f9996aaSopenharmony_ci        file_json = json.load(file)
2135f9996aaSopenharmony_ci        os_level = file_json["os_level"]
2145f9996aaSopenharmony_ci        out_path = file_json["out_path"]
2155f9996aaSopenharmony_ci        board = file_json["board"]
2165f9996aaSopenharmony_ci        product = file_json["product"]
2175f9996aaSopenharmony_ci    return (out_path, board, product, os_level)
2185f9996aaSopenharmony_ci
2195f9996aaSopenharmony_ci
2205f9996aaSopenharmony_cidef output_part_rom_status(root_path):
2215f9996aaSopenharmony_ci    ohos_config = read_ohos_config(root_path)
2225f9996aaSopenharmony_ci    if ohos_config[3] == "mini":
2235f9996aaSopenharmony_ci        return -1
2245f9996aaSopenharmony_ci    elif ohos_config[3] == "small":
2255f9996aaSopenharmony_ci        return -1
2265f9996aaSopenharmony_ci    else:
2275f9996aaSopenharmony_ci        part_paths = read_subsystem_config(root_path)
2285f9996aaSopenharmony_ci        for part_path in part_paths:
2295f9996aaSopenharmony_ci            part_root_path = os.path.join(root_path, part_path)
2305f9996aaSopenharmony_ci            if os.path.isdir(part_root_path):
2315f9996aaSopenharmony_ci                collect_bundle_json_path(part_root_path)
2325f9996aaSopenharmony_ci        for json_file in budle_json_files:
2335f9996aaSopenharmony_ci            if os.path.exists(json_file):
2345f9996aaSopenharmony_ci                read_bundle_json_file(json_file)
2355f9996aaSopenharmony_ci        actual_rom_statistics(ohos_config[0])
2365f9996aaSopenharmony_ci    return 0
237