• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2021 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15import ast
16import os
17import shutil
18import zipfile
19
20from test.fake_data import RSA_PRIVATE_KEY_DATA
21
22UPDATER_BINARY_DATA = b"updater binary data"
23BOARD_LIST_DATA = b"""HI3516
24HI3518
25HI3559"""
26VERSION_MBN_DATA = b"""Hi3516DV300-eng 10 QP1A.190711.020
27Hi3516DV300-eng 10 QP1A.190711.021"""
28
29UPDATER_SPECIFIED_CONFIG_XML_DATA = """<?xml version="1.0"?>
30<package>
31    <head name="Component header information">
32        <info fileVersion="01" prdID="123456"
33        softVersion="Hi3516DV300-eng 10 QP1A.190711.0VERSION_MARK"
34        date="2021-01-23" time="12:30">head info</info>
35    </head>
36    <group name = "Component information">
37        SYSTEM_MARK
38        COMPONENT_MARK
39    </group>
40</package>"""
41UPDATER_PARTITIONS_XML_DATA = b"""<?xml version="1.0" encoding="GB2312" ?>
42<Partition_Info>
43<Part PartitionName="boot" FlashType="emmc" FileSystem="none"
44    Start="0" Length="1M"/>
45<Part PartitionName="kernel" FlashType="emmc" FileSystem="none"
46    Start="1M" Length="15M"/>
47<Part PartitionName="updater" FlashType="emmc" FileSystem="ext3/4"
48    Start="16M" Length="20M"/>
49<Part PartitionName="misc" FlashType="emmc" FileSystem="none"
50    Start="36M" Length="1M"/>
51<Part PartitionName="system" FlashType="emmc" FileSystem="ext3/4"
52    Start="37M" Length="3300M"/>
53<Part PartitionName="vendor" FlashType="emmc" FileSystem="ext3/4"
54    Start="3337M" Length="263M"/>
55<Part PartitionName="userdata" FlashType="emmc" FileSystem="ext3/4"
56    Start="3600M" Length="1464M"/>
57</Partition_Info>"""
58
59SYSTEM_COMPONENT_STR = """<component compAddr="system" compId="12"
60        resType="05" compType="0" compVer="0o00">./system.img</component>"""
61COMPONENT_STR_INC = """<component compAddr="vendor" compId="13"
62        resType="05" compType="1" compVer="0o00">./vendor.img</component>"""
63COMPONENT_STR_FULL = """<component compAddr="vendor" compId="13"
64        resType="05" compType="0" compVer="0o00">./vendor.img</component>"""
65COMPONENT_STR_USERDATA = """<component compAddr="userdata" compId="14"
66        resType="05" compType="0" compVer="0o00">./userdata.img</component>"""
67SOURCE_VERSION_STR = "20"
68TARGET_VERSION_STR = "21"
69
70
71def create_input_package(
72        package_name, package_type="target", is_su=False,
73        is_updater_partitions=False, has_userdata=False,
74        is_inc_full_none=False, is_miss_image=False,
75        is_miss_version_list=False, is_miss_updater_binary=False):
76    """
77    Create input package.
78    :param package_name: package name
79    :param package_type: package type, source or target
80    :param is_su: Is it an updater upgrade package
81    :param is_updater_partitions: Is it an updater partitions upgrade package
82    :param has_userdata: Configuring UserData in XML
83    :param is_inc_full_none: Both full and incremental list lengths are zero
84    :param is_miss_image: Is image missing
85    :param is_miss_version_list: Is VERSION.list missing
86    :param is_miss_updater_binary: Is updater_binary missing
87    :return:
88    """
89    # Create a folder for the input package.
90    package_name_path = "./%s" % package_name
91    if not os.path.exists(package_name_path):
92        os.mkdir(package_name_path)
93
94    if not is_miss_image:
95        create_file(os.path.join(package_name_path, "system.img"),
96                    get_target_vendor_data())
97
98    # Judge the type of input package and generate the corresponding vendor.img
99    if package_type == "target":
100        vendor_content = get_target_vendor_data()
101    elif package_type == "source":
102        vendor_content = get_source_vendor_data()
103    else:
104        print("Unknown package type!")
105        raise RuntimeError
106    if not is_miss_image:
107        create_file(os.path.join(package_name_path, "vendor.img"),
108                    vendor_content)
109    if not is_miss_updater_binary:
110        create_file(os.path.join(package_name_path, "updater_binary"),
111                    UPDATER_BINARY_DATA)
112    # updater upgrade package
113    if is_su:
114        create_file(os.path.join(package_name_path, "uImage"),
115                    get_target_vendor_data())
116        create_file(os.path.join(package_name_path, "updater.img"),
117                    get_target_vendor_data())
118        create_file(os.path.join(package_name_path, "updater_b.img"),
119                    get_target_vendor_data())
120        create_file(os.path.join(package_name_path, "updater_uImage"),
121                    get_target_vendor_data())
122    # Create updater_config dir.
123    updater_config_path = "./%s/updater_config" % package_name
124    if not os.path.exists(updater_config_path):
125        os.mkdir(updater_config_path)
126    create_file(os.path.join(updater_config_path, "BOARD.list"),
127                BOARD_LIST_DATA)
128    if not is_miss_version_list:
129        create_file(os.path.join(updater_config_path, "VERSION.mbn"),
130                    VERSION_MBN_DATA)
131    # Judge the type of input package and
132    xml_content = \
133        create_updater_specified_config_file(
134            has_userdata, is_updater_partitions, package_type)
135
136    if is_inc_full_none:
137        xml_content = xml_content.replace("SYSTEM_MARK", "")
138        xml_content = xml_content.replace(
139            "COMPONENT_MARK", "").encode()
140    else:
141        xml_content = xml_content.replace(
142            "SYSTEM_MARK", SYSTEM_COMPONENT_STR)
143        xml_content = xml_content.replace(
144            "COMPONENT_MARK", COMPONENT_STR_FULL).encode()
145
146    create_file(
147        os.path.join(updater_config_path, "updater_specified_config.xml"),
148        xml_content)
149    # Create partition_file.xml.
150    if is_updater_partitions:
151        create_file("./partition_file.xml", UPDATER_PARTITIONS_XML_DATA)
152    # Create rsa_private_key2048.pem.
153    create_file("./rsa_private_key2048.pem", RSA_PRIVATE_KEY_DATA)
154    # Create zip package.
155    with zipfile.ZipFile('./%s.zip' % package_name,
156                         'w', zipfile.ZIP_DEFLATED) as package_zip:
157        package_zip.write(package_name_path)
158        for home, dirs, files in os.walk(package_name_path):
159            for each_file_name in files:
160                package_zip.write(os.path.join(home, each_file_name))
161            for each_dir_name in dirs:
162                package_zip.write(os.path.join(home, each_dir_name))
163
164
165def create_updater_specified_config_file(
166        has_userdata, is_updater_partitions, package_type):
167    """
168    generate the corresponding updater_specified_config.xml
169    :param has_userdata: has userdata
170    :param is_updater_partitions: is updater partitions
171    :param package_type: package type
172    :return:
173    """
174    if package_type == "target":
175        xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace(
176            "VERSION_MARK", TARGET_VERSION_STR)
177        xml_content = xml_content.replace(
178            "COMPONENT_MARK", COMPONENT_STR_INC)
179    elif package_type == "source":
180        xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace(
181            "VERSION_MARK", SOURCE_VERSION_STR)
182        if is_updater_partitions:
183            xml_content = xml_content.replace(
184                "COMPONENT_MARK", COMPONENT_STR_FULL)
185        elif has_userdata:
186            xml_content = xml_content.replace(
187                "COMPONENT_MARK", COMPONENT_STR_USERDATA)
188    else:
189        print("Unknown package type!")
190        raise RuntimeError
191    return xml_content
192
193
194def create_file(file_path, file_data):
195    """
196    Create file
197    :param file_path: file path
198    :param file_data: file data
199    :return:
200    """
201    with open(file_path, "wb") as w_f:
202        w_f.write(file_data)
203
204
205def clear_package(package_name):
206    """
207    Clean up the constructed input package and files
208    :param package_name: constructed input package name
209    :return:
210    """
211    if os.path.exists("./%s" % package_name):
212        shutil.rmtree("./%s" % package_name)
213    if os.path.exists("./%s.zip" % package_name):
214        os.remove("./%s.zip" % package_name)
215    if os.path.exists("./partition_file.xml"):
216        os.remove("./partition_file.xml")
217    if os.path.exists("./rsa_private_key2048.pem"):
218        os.remove("./rsa_private_key2048.pem")
219
220
221def get_source_vendor_data():
222    """
223    Get source vendor image file data
224    :return:
225    """
226    with open(r"./source_vendor_data", "r") as r_f:
227        content = r_f.read()
228        return ast.literal_eval(content)
229
230
231def get_target_vendor_data():
232    """
233    Get target vendor image file data
234    :return:
235    """
236    with open(r"./target_vendor_data", "r") as r_f:
237        content = r_f.read()
238        return ast.literal_eval(content)
239