1#!/usr/bin/env python 2# coding: utf-8 3 4""" 5Copyright (c) 2025 Huawei Device Co., Ltd. 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17 18""" 19 20import json 21import argparse 22import os 23import stat 24import hashlib 25 26PERMISSION_DEFINITION_PREFIX = ''' 27/* 28 * Copyright (c) 2025 Huawei Device Co., Ltd. 29 * Licensed under the Apache License, Version 2.0 (the "License"); 30 * you may not use this file except in compliance with the License. 31 * You may obtain a copy of the License at 32 * 33 * http://www.apache.org/licenses/LICENSE-2.0 34 * 35 * Unless required by applicable law or agreed to in writing, software 36 * distributed under the License is distributed on an "AS IS" BASIS, 37 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 38 * See the License for the specific language governing permissions and 39 * limitations under the License. 40 */ 41 42#ifndef PERMISSION_DEFINITION_PARSER_H 43#define PERMISSION_DEFINITION_PARSER_H 44 45#include "permission_map.h" 46 47namespace OHOS { 48namespace Security { 49namespace AccessToken { 50''' 51 52PERMISSION_DEFINITION_SUFFIX_1 = ''' 53}; 54''' 55 56PERMISSION_DEFINITION_SUFFIX_2 = ''' 57const uint32_t MAX_PERM_SIZE = sizeof(g_permList) / sizeof(PermissionBriefDef); 58} // namespace AccessToken 59} // namespace Security 60} // namespace OHOS 61#endif // PERMISSION_DEFINITION_PARSER_H 62''' 63 64PERMISSION_NAME_STRING = "char PERMISSION_NAME_%i[] = \"%s\";\n" 65 66PERMISSION_LIST_DECLEARE = "const static PermissionBriefDef g_permList[] = {" 67 68VERSION_STRING = "\nconst char* PERMISSION_DEFINITION_VERSION = \"%s\";" 69 70PERMISSION_BRIEF_DEFINE_PATTERN = ''' 71{ 72 .permissionName = PERMISSION_NAME_%i, 73 .grantMode = %s, 74 .availableLevel = %s, 75 .availableType = %s, 76 .provisionEnable = %s, 77 .distributedSceneEnable = %s, 78 .isKernelEffect = %s, 79 .hasValue = %s 80},''' 81 82JSON_VALUE_CONVERT_TO_CPP_DICT = { 83 "user_grant": "USER_GRANT", 84 "system_grant": "SYSTEM_GRANT", 85 "normal": "APL_NORMAL", 86 "system_basic": "APL_SYSTEM_BASIC", 87 "system_core": "APL_SYSTEM_CORE", 88} 89 90CONVERT_TARGET_PLATFORM = { 91 "phone": "phone", 92 "watch": "wearable", 93 "wearable": "wearable", 94 "tablet": "tablet", 95 "pc": "2in1", 96 "tv": "tv", 97 "car": "car", 98} 99 100 101class PermissionDef(object): 102 def __init__(self, permission_def_dict, code): 103 self.name = permission_def_dict["name"] 104 self.grant_mode = JSON_VALUE_CONVERT_TO_CPP_DICT[ 105 permission_def_dict["grantMode"]] 106 107 self.available_level = JSON_VALUE_CONVERT_TO_CPP_DICT[ 108 permission_def_dict["availableLevel"] 109 ] 110 self.available_type = permission_def_dict["availableType"] 111 112 if "provisionEnable" in permission_def_dict and permission_def_dict["provisionEnable"]: 113 self.provision_enable = "true" 114 else: 115 self.provision_enable = "false" 116 117 if "distributedSceneEnable" in permission_def_dict and permission_def_dict["distributedSceneEnable"]: 118 self.distributed_scene_enable = "true" 119 else: 120 self.distributed_scene_enable = "false" 121 122 if "isKernelEffect" in permission_def_dict and permission_def_dict["isKernelEffect"]: 123 self.is_kernel_effect = "true" 124 else: 125 self.is_kernel_effect = "false" 126 127 if "hasValue" in permission_def_dict and permission_def_dict["hasValue"]: 128 self.has_value = "true" 129 else: 130 self.has_value = "false" 131 132 if permission_def_dict["since"] >= 20 and not "deviceTypes" in permission_def_dict: 133 raise Exception("No deviceTypes in permission difinition of {}".format(self.name)) 134 135 if "deviceTypes" in permission_def_dict: 136 if isinstance(permission_def_dict["deviceTypes"], list) and len(permission_def_dict["deviceTypes"]) > 0: 137 self.device_types = permission_def_dict["deviceTypes"] 138 else: 139 raise Exception("Must be filled with available device type list, name = {}".format(self.name)) 140 else: 141 self.device_types = ["general"] 142 143 self.code = code 144 145 def dump_permission_name(self): 146 return PERMISSION_NAME_STRING % ( 147 self.code, self.name 148 ) 149 150 def dump_struct(self): 151 entry = PERMISSION_BRIEF_DEFINE_PATTERN % ( 152 self.code, self.grant_mode, self.available_level, 153 self.available_type, self.provision_enable, self.distributed_scene_enable, 154 self.is_kernel_effect, self.has_value 155 ) 156 return entry 157 158 def check_device_type(self, target_platform): 159 if "general" in self.device_types: 160 return True 161 if target_platform in self.device_types: 162 return True 163 return False 164 165 166def parse_json(path, platform): 167 extend_perm = { 168 'name' : 'ohos.permission.KERNEL_ATM_SELF_USE', 169 'grantMode' : 'system_grant', 170 'availableLevel' : 'system_core', 171 'availableType' : 'SYSTEM', 172 'since' : 18, 173 'deprecated' : '', 174 'provisionEnable' : True, 175 'distributedSceneEnable' : True, 176 'isKernelEffect' : True, 177 'hasValue' : True 178 } 179 180 def_list = [] 181 with open(path, "r", encoding="utf-8") as f: 182 data = json.load(f) 183 index = 0 184 for perm in data["definePermissions"]: 185 perm_def = PermissionDef(perm, index) 186 if not perm_def.check_device_type(platform): 187 continue 188 def_list.append(perm_def) 189 index += 1 190 def_list.append(PermissionDef(extend_perm, index)) 191 return def_list 192 193 194def convert_to_cpp(path, permission_list, hash_str): 195 flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC 196 mode = stat.S_IWUSR | stat.S_IRUSR 197 with os.fdopen(os.open(path, flags, mode), "w") as f: 198 f.write(PERMISSION_DEFINITION_PREFIX) 199 for perm in permission_list: 200 f.write(perm.dump_permission_name()) 201 f.write(PERMISSION_LIST_DECLEARE) 202 for perm in permission_list: 203 f.write(perm.dump_struct()) 204 f.write(PERMISSION_DEFINITION_SUFFIX_1) 205 f.write(VERSION_STRING % (hash_str)) 206 f.write(PERMISSION_DEFINITION_SUFFIX_2) 207 208 209def parse_args(): 210 parser = argparse.ArgumentParser() 211 parser.add_argument('--output-path', help='the output cpp path', required=True) 212 parser.add_argument('--input-json', help='json file for permission difinition', required=True) 213 parser.add_argument('--target-platform', help='build target platform', required=True) 214 return parser.parse_args() 215 216 217def get_file_hash(path): 218 hash_object = hashlib.sha256() 219 with open(path, 'rb') as f: 220 while line := f.read(4096): 221 hash_object.update(line) 222 return hash_object.hexdigest() 223 224if __name__ == "__main__": 225 input_args = parse_args() 226 curr_platform = "general" 227 if input_args.target_platform in CONVERT_TARGET_PLATFORM: 228 curr_platform = CONVERT_TARGET_PLATFORM[input_args.target_platform] 229 permission_list = parse_json(input_args.input_json, curr_platform) 230 hash_str = get_file_hash(input_args.input_json) 231 convert_to_cpp(input_args.output_path, permission_list, hash_str) 232