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