123b3eb3cSopenharmony_ci#!/usr/bin/env python
223b3eb3cSopenharmony_ci# -*- coding: utf-8 -*-
323b3eb3cSopenharmony_ci
423b3eb3cSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd.
523b3eb3cSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
623b3eb3cSopenharmony_ci# you may not use this file except in compliance with the License.
723b3eb3cSopenharmony_ci# You may obtain a copy of the License at
823b3eb3cSopenharmony_ci#
923b3eb3cSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
1023b3eb3cSopenharmony_ci#
1123b3eb3cSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
1223b3eb3cSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
1323b3eb3cSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1423b3eb3cSopenharmony_ci# See the License for the specific language governing permissions and
1523b3eb3cSopenharmony_ci# limitations under the License.
1623b3eb3cSopenharmony_ci
1723b3eb3cSopenharmony_ciimport os
1823b3eb3cSopenharmony_ciimport struct
1923b3eb3cSopenharmony_ciimport sys
2023b3eb3cSopenharmony_ci
2123b3eb3cSopenharmony_ci
2223b3eb3cSopenharmony_cidef int_to_str(int_n):
2323b3eb3cSopenharmony_ci    buf = ""
2423b3eb3cSopenharmony_ci    i = 0
2523b3eb3cSopenharmony_ci    while i < 4:
2623b3eb3cSopenharmony_ci        a = ((int_n >> (3 - i) * 8) & 0xff)
2723b3eb3cSopenharmony_ci        if a != 0:
2823b3eb3cSopenharmony_ci            buf = buf + chr(a)
2923b3eb3cSopenharmony_ci        i = i + 1
3023b3eb3cSopenharmony_ci    return buf
3123b3eb3cSopenharmony_ci
3223b3eb3cSopenharmony_ci
3323b3eb3cSopenharmony_ciresolutions = {-2: "nodpi", -1: "anydpi", 120: "sdpi", 160: "mdpi", 213: "tvdpi", 240: "ldpi", 320: "xldpi",
3423b3eb3cSopenharmony_ci               480: "xxldpi", 640: "xxxldpi"}
3523b3eb3cSopenharmony_ci
3623b3eb3cSopenharmony_ciorientations = {0: "vertical", 1: "horizontal"}
3723b3eb3cSopenharmony_ci
3823b3eb3cSopenharmony_cidevices = {0: "phone", 1: "tablet", 2: "car", 3: "pc", 4: "tv", 5: "speaker", 6: "wearable", 7: "glasses", 8: "headset"}
3923b3eb3cSopenharmony_ci
4023b3eb3cSopenharmony_cinight_modes = {0: "dark", 1: "light"}
4123b3eb3cSopenharmony_ci
4223b3eb3cSopenharmony_ci
4323b3eb3cSopenharmony_cidef parse_limit_key(limit_key):
4423b3eb3cSopenharmony_ci    key_str = ""
4523b3eb3cSopenharmony_ci    key_ = limit_key
4623b3eb3cSopenharmony_ci    if key_ == "":
4723b3eb3cSopenharmony_ci        key_ = "base"
4823b3eb3cSopenharmony_ci        key_str = "base"
4923b3eb3cSopenharmony_ci
5023b3eb3cSopenharmony_ci    key_sets = key_.split("-")
5123b3eb3cSopenharmony_ci    last_key_type = -1
5223b3eb3cSopenharmony_ci    for key_item in key_sets:
5323b3eb3cSopenharmony_ci        if key_item == "base":
5423b3eb3cSopenharmony_ci            continue
5523b3eb3cSopenharmony_ci        key_s = key_item.split(":")
5623b3eb3cSopenharmony_ci        if int(key_s[0]) == 0 or int(key_s[0]) == 1 or int(key_s[0]) == 5:
5723b3eb3cSopenharmony_ci            i = int(key_s[1])
5823b3eb3cSopenharmony_ci            if key_str == "":
5923b3eb3cSopenharmony_ci                key_str = key_str + int_to_str(i)
6023b3eb3cSopenharmony_ci            elif last_key_type == 0 or last_key_type == 1 or last_key_type == 5:
6123b3eb3cSopenharmony_ci                key_str = "{}_{}".format(key_str, int_to_str(i))
6223b3eb3cSopenharmony_ci            else:
6323b3eb3cSopenharmony_ci                key_str = "{}-{}".format(key_str, int_to_str(i))
6423b3eb3cSopenharmony_ci            last_key_type = int(key_s[0])
6523b3eb3cSopenharmony_ci        elif int(key_s[0]) == 2:
6623b3eb3cSopenharmony_ci            k = int(key_s[1])
6723b3eb3cSopenharmony_ci            if (k & 0x80000000) != 0:
6823b3eb3cSopenharmony_ci                a = (0xffffffff ^ k) + 1
6923b3eb3cSopenharmony_ci                k = -1 * a
7023b3eb3cSopenharmony_ci            if key_str == "":
7123b3eb3cSopenharmony_ci                key_str = key_str + resolutions.get(k)
7223b3eb3cSopenharmony_ci            else:
7323b3eb3cSopenharmony_ci                key_str = "{}-{}".format(key_str, resolutions.get(k))
7423b3eb3cSopenharmony_ci        elif int(key_s[0]) == 3:
7523b3eb3cSopenharmony_ci            if key_str == "":
7623b3eb3cSopenharmony_ci                key_str = key_str + orientations.get(int(key_s[1]))
7723b3eb3cSopenharmony_ci            else:
7823b3eb3cSopenharmony_ci                key_str = "{}-{}".format(key_str, orientations.get(int(key_s[1])))
7923b3eb3cSopenharmony_ci        elif int(key_s[0]) == 4:
8023b3eb3cSopenharmony_ci            if key_str == "":
8123b3eb3cSopenharmony_ci                key_str = key_str + devices.get(int(key_s[1]))
8223b3eb3cSopenharmony_ci            else:
8323b3eb3cSopenharmony_ci                key_str = "{}-{}".format(key_str, devices.get(int(key_s[1])))
8423b3eb3cSopenharmony_ci        elif int(key_s[0]) == 6:
8523b3eb3cSopenharmony_ci            if key_str == "":
8623b3eb3cSopenharmony_ci                key_str = key_str + night_modes.get(int(key_s[1]))
8723b3eb3cSopenharmony_ci            else:
8823b3eb3cSopenharmony_ci                key_str = "{}-{}".format(key_str, night_modes.get(int(key_s[1])))
8923b3eb3cSopenharmony_ci        elif int(key_s[0]) == 7:
9023b3eb3cSopenharmony_ci            i = int(key_s[1])
9123b3eb3cSopenharmony_ci            if key_str == "":
9223b3eb3cSopenharmony_ci                key_str = "{}mcc{}".format(key_str, str(i))
9323b3eb3cSopenharmony_ci            else:
9423b3eb3cSopenharmony_ci                key_str = "{}_mcc{}".format(key_str, str(i))
9523b3eb3cSopenharmony_ci        elif int(key_s[0]) == 8:
9623b3eb3cSopenharmony_ci            i = int(key_s[1])
9723b3eb3cSopenharmony_ci            if key_str == "":
9823b3eb3cSopenharmony_ci                key_str = "{}mnc{:0>2d}".format(key_str, i)
9923b3eb3cSopenharmony_ci            else:
10023b3eb3cSopenharmony_ci                key_str = "{}_mnc{:0>2d}".format(key_str, i)
10123b3eb3cSopenharmony_ci        else:
10223b3eb3cSopenharmony_ci            raise Exception("invalid key={}".format(str(int(key_s[0]))))
10323b3eb3cSopenharmony_ci    return key_str
10423b3eb3cSopenharmony_ci
10523b3eb3cSopenharmony_ci
10623b3eb3cSopenharmony_cidef open_new_resource_index(file_path):
10723b3eb3cSopenharmony_ci    if not os.path.exists(file_path):
10823b3eb3cSopenharmony_ci        raise Exception("not found:" + file_path)
10923b3eb3cSopenharmony_ci
11023b3eb3cSopenharmony_ci    with open(file_path, "rb") as fp_resource_index:
11123b3eb3cSopenharmony_ci        header = fp_resource_index.read(128)
11223b3eb3cSopenharmony_ci        length = fp_resource_index.read(4)
11323b3eb3cSopenharmony_ci        key_count = fp_resource_index.read(4)
11423b3eb3cSopenharmony_ci        pri_key_count = struct.unpack("i", key_count)[0]
11523b3eb3cSopenharmony_ci
11623b3eb3cSopenharmony_ci        index_one = 0
11723b3eb3cSopenharmony_ci
11823b3eb3cSopenharmony_ci        # keys
11923b3eb3cSopenharmony_ci        private_index = {}
12023b3eb3cSopenharmony_ci        while index_one < pri_key_count:
12123b3eb3cSopenharmony_ci            buf = fp_resource_index.read(4)
12223b3eb3cSopenharmony_ci            p_key_tag = struct.unpack("4s", buf)[0]
12323b3eb3cSopenharmony_ci
12423b3eb3cSopenharmony_ci            buf = fp_resource_index.read(4)
12523b3eb3cSopenharmony_ci            p_data_offset = struct.unpack("I", buf)[0]
12623b3eb3cSopenharmony_ci
12723b3eb3cSopenharmony_ci            buf = fp_resource_index.read(4)
12823b3eb3cSopenharmony_ci            p_key_count = struct.unpack("I", buf)[0]
12923b3eb3cSopenharmony_ci
13023b3eb3cSopenharmony_ci            i = 0
13123b3eb3cSopenharmony_ci            key_str = ""
13223b3eb3cSopenharmony_ci            while i < p_key_count:
13323b3eb3cSopenharmony_ci                buf = fp_resource_index.read(8)
13423b3eb3cSopenharmony_ci                p_key_type = struct.unpack("I", buf[0:4])[0]
13523b3eb3cSopenharmony_ci                p_value = struct.unpack("I", buf[4:8])[0]
13623b3eb3cSopenharmony_ci                if key_str == "":
13723b3eb3cSopenharmony_ci                    key_str = "{}:{}".format(str(p_key_type), str(p_value))
13823b3eb3cSopenharmony_ci                else:
13923b3eb3cSopenharmony_ci                    key_str = "{}-{}:{}".format(key_str, str(p_key_type), str(p_value))
14023b3eb3cSopenharmony_ci                i = i + 1
14123b3eb3cSopenharmony_ci            private_index[key_str] = p_data_offset
14223b3eb3cSopenharmony_ci            index_one = index_one + 1
14323b3eb3cSopenharmony_ci
14423b3eb3cSopenharmony_ci        # idss
14523b3eb3cSopenharmony_ci        c = 0
14623b3eb3cSopenharmony_ci        idss_cache = {}
14723b3eb3cSopenharmony_ci        while c < pri_key_count:
14823b3eb3cSopenharmony_ci            pos = fp_resource_index.tell()
14923b3eb3cSopenharmony_ci            idss_buf = fp_resource_index.read(4)
15023b3eb3cSopenharmony_ci            idss_tag = struct.unpack("4s", idss_buf)[0]
15123b3eb3cSopenharmony_ci            idss_buf = fp_resource_index.read(4)
15223b3eb3cSopenharmony_ci            idss_count = struct.unpack("I", idss_buf)[0]
15323b3eb3cSopenharmony_ci            i = 0
15423b3eb3cSopenharmony_ci            idss_index = {}
15523b3eb3cSopenharmony_ci            while i < idss_count:
15623b3eb3cSopenharmony_ci                buf = fp_resource_index.read(4)
15723b3eb3cSopenharmony_ci                p_id = struct.unpack("I", buf)[0]
15823b3eb3cSopenharmony_ci                buf = fp_resource_index.read(4)
15923b3eb3cSopenharmony_ci                p_offset = struct.unpack("I", buf)[0]
16023b3eb3cSopenharmony_ci                idss_index[p_id] = p_offset
16123b3eb3cSopenharmony_ci                i = i + 1
16223b3eb3cSopenharmony_ci            idss_cache[pos] = idss_index
16323b3eb3cSopenharmony_ci            c = c + 1
16423b3eb3cSopenharmony_ci
16523b3eb3cSopenharmony_ci        third_data = {}
16623b3eb3cSopenharmony_ci        d_data = {}
16723b3eb3cSopenharmony_ci        d_pos = fp_resource_index.tell()
16823b3eb3cSopenharmony_ci        d_buf = fp_resource_index.read(4)
16923b3eb3cSopenharmony_ci        while len(d_buf) > 0:
17023b3eb3cSopenharmony_ci            d_size = struct.unpack("I", d_buf)[0]
17123b3eb3cSopenharmony_ci            d_buf = fp_resource_index.read(d_size)
17223b3eb3cSopenharmony_ci            d_res_type = struct.unpack("I", d_buf[0:4])[0]
17323b3eb3cSopenharmony_ci
17423b3eb3cSopenharmony_ci            d_value_len_l = struct.unpack("B", d_buf[8:9])[0]
17523b3eb3cSopenharmony_ci            d_value_len_h = struct.unpack("B", d_buf[9:10])[0]
17623b3eb3cSopenharmony_ci            d_value_len = d_value_len_l + d_value_len_h * 256
17723b3eb3cSopenharmony_ci            d_value = ""
17823b3eb3cSopenharmony_ci            if d_res_type == 10 or d_res_type == 11 or d_res_type == 16 or d_res_type == 17 or d_res_type == 22:
17923b3eb3cSopenharmony_ci                tmp = d_buf[10:10 + d_value_len]
18023b3eb3cSopenharmony_ci                d_d_pos = 0
18123b3eb3cSopenharmony_ci                while d_d_pos < d_value_len - 1:
18223b3eb3cSopenharmony_ci                    d_d_value_len_l = struct.unpack("B", tmp[0 + d_d_pos:1 + d_d_pos])[0]
18323b3eb3cSopenharmony_ci                    d_d_value_len_h = struct.unpack("B", tmp[1 + d_d_pos:2 + d_d_pos])[0]
18423b3eb3cSopenharmony_ci                    d_d_value_len = d_d_value_len_l + d_d_value_len_h * 256
18523b3eb3cSopenharmony_ci                    d_value = "{}<{}>".format(d_value, str(tmp[2 + d_d_pos:2 + d_d_value_len + d_d_pos]))
18623b3eb3cSopenharmony_ci                    d_d_pos = d_d_pos + 2 + d_d_value_len + 1
18723b3eb3cSopenharmony_ci            else:
18823b3eb3cSopenharmony_ci                d_value = d_buf[10:10 + d_value_len - 1].decode("utf-8")
18923b3eb3cSopenharmony_ci
19023b3eb3cSopenharmony_ci            d_name_len_l = struct.unpack("B", d_buf[10 + d_value_len:11 + d_value_len])[0]
19123b3eb3cSopenharmony_ci            d_name_len_h = struct.unpack("B", d_buf[11 + d_value_len:12 + d_value_len])[0]
19223b3eb3cSopenharmony_ci            d_name_len = d_name_len_l + d_name_len_h * 256
19323b3eb3cSopenharmony_ci            d_name = str(d_buf[12 + d_value_len:12 + d_value_len + d_name_len - 1].decode("utf-8"))
19423b3eb3cSopenharmony_ci            d_data[d_pos] = [d_value, d_name]
19523b3eb3cSopenharmony_ci
19623b3eb3cSopenharmony_ci            d_pos = fp_resource_index.tell()
19723b3eb3cSopenharmony_ci            d_buf = fp_resource_index.read(4)
19823b3eb3cSopenharmony_ci
19923b3eb3cSopenharmony_ci    for key_, key_offset in private_index.items():
20023b3eb3cSopenharmony_ci        third_data[key_] = {}
20123b3eb3cSopenharmony_ci        idss_sets = idss_cache.get(key_offset)
20223b3eb3cSopenharmony_ci        for id_, offset in idss_sets.items():
20323b3eb3cSopenharmony_ci            id_sets = d_data.get(offset)
20423b3eb3cSopenharmony_ci            third_data[key_][id_] = id_sets
20523b3eb3cSopenharmony_ci    return third_data
20623b3eb3cSopenharmony_ci
20723b3eb3cSopenharmony_ci
20823b3eb3cSopenharmony_cidef dump(file_path, out_path):
20923b3eb3cSopenharmony_ci    out_file = os.open(out_path, os.O_WRONLY | os.O_CREAT, 0o664)
21023b3eb3cSopenharmony_ci    third_data = open_new_resource_index(file_path)
21123b3eb3cSopenharmony_ci    for key_, ids_ in third_data.items():
21223b3eb3cSopenharmony_ci        key_str = parse_limit_key(key_)
21323b3eb3cSopenharmony_ci        if "zh_CN" == key_str:
21423b3eb3cSopenharmony_ci            continue
21523b3eb3cSopenharmony_ci        os.write(out_file, str.encode("keyconfig:{}\n".format(key_)))
21623b3eb3cSopenharmony_ci        os.write(out_file, str.encode("{}\n".format(key_str)))
21723b3eb3cSopenharmony_ci        for id_, idsets in ids_.items():
21823b3eb3cSopenharmony_ci            os.write(out_file, str.encode("id:{}, '{}' '{}'\n".format(str(id_), idsets[0], str(idsets[1]))))
21923b3eb3cSopenharmony_ci    os.close(out_file)
220