1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3""" 4Copyright 2023 Huawei Device Co., Ltd. 5Licensed under the Apache License, Version 2.0 (the "License"); 6you may not use this file except in compliance with the License. 7You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11Unless required by applicable law or agreed to in writing, software 12distributed under the License is distributed on an "AS IS" BASIS, 13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14See the License for the specific language governing permissions and 15limitations under the License. 16 17""" 18 19import os 20import re 21import json 22 23from util.log_util import LogUtil 24from resources.config import Config 25 26budle_json_files = [] 27standard_part_roms = [] 28part_info_list = [] 29 30 31def part_size_compare(module_info_list, part_name, part_size): 32 for standard_part in standard_part_roms: 33 if standard_part['part_name'] == part_name and standard_part['part_size'] != 'None': 34 sta_size = re.findall(r"\d+", standard_part['part_size']) 35 rea_size = re.findall(r"\d+", part_size) 36 if int(sta_size[0]) >= int(rea_size[0]): 37 conform_str = ''.join(['part_name: {}'.format(part_name).ljust(55), \ 38 'actual_size: {}'.format(part_size).ljust(25), \ 39 'standard_size: {}'.format(standard_part['part_size']).ljust(25), \ 40 'conform to the rules']) 41 LogUtil.hb_info(conform_str) 42 part_info_dict = {} 43 part_info_dict["part_name"] = part_name 44 part_info_dict["actual_size"] = part_size 45 part_info_dict["standard_size"] = standard_part['part_size'] 46 part_info_dict["status_info"] = "'rom' conform to the rules" 47 part_info_dict["modules_info"] = module_info_list 48 part_info_list.append(part_info_dict) 49 50 elif int(sta_size[0]) < int(rea_size[0]): 51 out_of_standard_str = ''.join(['part_name: {}'.format(part_name).ljust(55), \ 52 'actual_size: {}'.format(part_size).ljust(25), \ 53 'standard_size: {}'.format(standard_part['part_size']).ljust(25), \ 54 'rom out of standard']) 55 LogUtil.hb_info(out_of_standard_str) 56 part_info_dict = {} 57 part_info_dict["part_name"] = part_name 58 part_info_dict["actual_size"] = part_size 59 part_info_dict["standard_size"] = standard_part['part_size'] 60 part_info_dict["status_info"] = "'rom' out of standard" 61 part_info_dict["modules_info"] = module_info_list 62 part_info_list.append(part_info_dict) 63 else: 64 if standard_part['part_name'] == part_name and standard_part['part_size'] == 'None': 65 not_yet_standard_str = ('part_name: {}'.format(part_name)).ljust(55) + \ 66 ('actual_size: {}'.format(part_size)).ljust(50) + \ 67 "This part does not set standard 'rom' size".ljust(25) 68 LogUtil.hb_info(not_yet_standard_str) 69 part_info_dict = {} 70 part_info_dict["part_name"] = part_name 71 part_info_dict["actual_size"] = part_size 72 part_info_dict["standard_size"] = standard_part['part_size'] 73 part_info_dict["status_info"] = "This part does not set standard 'rom' size" 74 part_info_dict["modules_info"] = module_info_list 75 part_info_list.append(part_info_dict) 76 77 78def collect_part_name(root_path): 79 install_parts = [] 80 file_path = os.path.join(root_path, "packages/phone/system_install_parts.json") 81 if os.path.isfile(file_path): 82 with open(file_path, 'rb') as file: 83 file_json = json.load(file) 84 for part_info in file_json: 85 part_info_dict = {} 86 part_info_dict["part_name"] = part_info["part_name"] 87 part_info_dict["part_info_file"] = part_info["part_info_file"] 88 install_parts.append(part_info_dict) 89 return install_parts 90 91 92def colletct_modules_json_path(out_path, install_parts): 93 module_info_list = [] 94 for part_info_dict in install_parts: 95 part_info_path = os.path.join(out_path, part_info_dict["part_info_file"]) 96 if os.path.isfile(part_info_path): 97 with open(part_info_path, 'rb') as file: 98 file_json = json.load(file) 99 for module_info in file_json: 100 if module_info["part_name"] == part_info_dict["part_name"]: 101 module_json_path = {} 102 module_json_path["module_info_path"] = module_info["module_info_file"] 103 module_json_path["part_name"] = module_info["part_name"] 104 module_info_list.append(module_json_path) 105 return module_info_list 106 107 108def sum_of_statistics(out_path, part_name, module_info_list): 109 part_so_size = 0 110 module_list = [] 111 for module_info in module_info_list: 112 if part_name == module_info['part_name']: 113 module_info_path = os.path.join(out_path, module_info['module_info_path']) 114 if os.path.isfile(module_info_path): 115 with open(module_info_path, 'rb') as file: 116 file_json = json.load(file) 117 so_file_dir = os.path.join(out_path, file_json["source"]) 118 if so_file_dir.endswith(".so") and os.path.isfile(so_file_dir): 119 module_info_dict = {} 120 module_info_dict["module_name"] = file_json["label_name"] 121 module_info_dict["source"] = file_json["source"] 122 module_info_dict["dest"] = file_json["dest"] 123 dest_num = len(file_json["dest"]) 124 so_file_size = os.path.getsize(so_file_dir) * dest_num 125 part_so_size += so_file_size 126 module_info_dict["module_size"] = f'{round(so_file_size / 1024, 2)}KB' 127 module_list.append(module_info_dict) 128 return module_list, part_so_size 129 130 131def check_image_size(out_path): 132 image_list = [] 133 image_path = os.path.join(out_path, 'packages/phone/images/') 134 if os.path.isdir(image_path): 135 for file in os.listdir(image_path): 136 if file.endswith(".img"): 137 image_dict = {} 138 img_path = os.path.join(image_path, file) 139 image_dict['img_size'] = f'{round(os.path.getsize(img_path) / 1024, 2)}KB' 140 image_dict['img_name'] = file 141 image_list.append(image_dict) 142 return image_list 143 144 145def actual_rom_statistics(out_path): 146 rom_statistics = {} 147 install_parts = collect_part_name(out_path) 148 module_info_list = colletct_modules_json_path(out_path, install_parts) 149 image_list = check_image_size(out_path) 150 rom_statistics["images_info"] = image_list 151 152 for part_info_dict in install_parts: 153 statistics_result = sum_of_statistics(out_path, part_info_dict["part_name"], module_info_list) 154 part_so_size = f'{round(statistics_result[1] / 1024, 2)}KB' 155 part_size_compare(statistics_result[0], 156 part_info_dict["part_name"], 157 part_so_size) 158 rom_statistics["parts_info"] = part_info_list 159 json_path = os.path.join(out_path, 'rom_statistics_table.json') 160 json_str = json.dumps(rom_statistics, indent=4) 161 with open(json_path, 'w') as json_file: 162 json_file.write(json_str) 163 164 165def read_bundle_json_file(file_path): 166 with open(file_path, 'rb') as file: 167 file_json = json.load(file) 168 standard_part_rom = {} 169 standard_part_rom["part_name"] = file_json["component"]["name"] 170 if 'rom' not in file_json["component"].keys() or file_json["component"]["rom"] == '': 171 standard_part_rom["part_size"] = 'None' 172 else: 173 standard_part_rom["part_size"] = file_json["component"]["rom"] 174 if standard_part_roms.count(standard_part_rom) == 0: 175 standard_part_roms.append(standard_part_rom) 176 177 178def collect_bundle_json_path(part_root_path): 179 for root, dirs, files in os.walk(part_root_path): 180 abs_path = os.path.abspath(root) 181 for file_name in files: 182 if file_name == 'bundle.json': 183 budle_json_files.append(os.path.join(abs_path, file_name)) 184 185 186def read_subsystem_config(root_path): 187 part_json_paths = [] 188 part_json_path = os.path.join(root_path, 'build/subsystem_config.json') 189 if os.path.isfile(part_json_path): 190 with open(part_json_path, 'r') as file: 191 file_json = json.load(file) 192 for part_info_valule in file_json.values(): 193 for path_k, path_v in part_info_valule.items(): 194 if path_k == "path": 195 part_json_paths.append(path_v) 196 config = Config() 197 part_json_overlay_path = config.product_path 198 if os.path.isfile(part_json_overlay_path): 199 with open(part_json_overlay_path, 'r') as file: 200 file_json = json.load(file) 201 for part_info_valule in file_json.values(): 202 for path_k, path_v in part_info_valule.items(): 203 if path_k == "path": 204 part_json_paths.append(path_v) 205 206 return part_json_paths 207 208 209def read_ohos_config(root_path): 210 file_path = os.path.join(root_path, "ohos_config.json") 211 with open(file_path, 'r') as file: 212 file_json = json.load(file) 213 os_level = file_json["os_level"] 214 out_path = file_json["out_path"] 215 board = file_json["board"] 216 product = file_json["product"] 217 return (out_path, board, product, os_level) 218 219 220def output_part_rom_status(root_path): 221 ohos_config = read_ohos_config(root_path) 222 if ohos_config[3] == "mini": 223 return -1 224 elif ohos_config[3] == "small": 225 return -1 226 else: 227 part_paths = read_subsystem_config(root_path) 228 for part_path in part_paths: 229 part_root_path = os.path.join(root_path, part_path) 230 if os.path.isdir(part_root_path): 231 collect_bundle_json_path(part_root_path) 232 for json_file in budle_json_files: 233 if os.path.exists(json_file): 234 read_bundle_json_file(json_file) 235 actual_rom_statistics(ohos_config[0]) 236 return 0 237