blob: ad991caab6b5191514597d3a956cd624b8896f8f [file] [log] [blame]
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001#!/usr/bin/env python
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
Daniel Norman4cc9df62019-07-18 10:11:07 -070016#
17"""This script merges two partial target files packages.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080018
Daniel Normand5d70ea2019-06-05 15:13:43 -070019One package contains framework files, and the other contains vendor files.
Daniel Normane5b134a2019-04-17 14:54:06 -070020It produces a complete target files package that can be used to generate an
21OTA package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080022
23Usage: merge_target_files.py [args]
24
Daniel Normand5d70ea2019-06-05 15:13:43 -070025 --framework-target-files framework-target-files-zip-archive
26 The input target files package containing framework bits. This is a zip
Bill Peckhame9eb5f92019-02-01 15:52:10 -080027 archive.
28
Daniel Normand5d70ea2019-06-05 15:13:43 -070029 --framework-item-list framework-item-list-file
Daniel Norman2c99c5b2019-03-07 13:01:48 -080030 The optional path to a newline-separated config file that replaces the
Daniel Normand5d70ea2019-06-05 15:13:43 -070031 contents of DEFAULT_FRAMEWORK_ITEM_LIST if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080032
Daniel Normand5d70ea2019-06-05 15:13:43 -070033 --framework-misc-info-keys framework-misc-info-keys-file
Daniel Norman2c99c5b2019-03-07 13:01:48 -080034 The optional path to a newline-separated config file that replaces the
Daniel Normand5d70ea2019-06-05 15:13:43 -070035 contents of DEFAULT_FRAMEWORK_MISC_INFO_KEYS if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080036
Daniel Normand5d70ea2019-06-05 15:13:43 -070037 --vendor-target-files vendor-target-files-zip-archive
38 The input target files package containing vendor bits. This is a zip
Bill Peckhame9eb5f92019-02-01 15:52:10 -080039 archive.
40
Daniel Normand5d70ea2019-06-05 15:13:43 -070041 --vendor-item-list vendor-item-list-file
Daniel Norman2c99c5b2019-03-07 13:01:48 -080042 The optional path to a newline-separated config file that replaces the
Daniel Normand5d70ea2019-06-05 15:13:43 -070043 contents of DEFAULT_VENDOR_ITEM_LIST if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080044
Bill Peckhame9eb5f92019-02-01 15:52:10 -080045 --output-target-files output-target-files-package
Daniel Normanfdb38812019-04-15 09:47:24 -070046 If provided, the output merged target files package. Also a zip archive.
47
48 --output-dir output-directory
49 If provided, the destination directory for saving merged files. Requires
50 the --output-item-list flag.
51 Can be provided alongside --output-target-files, or by itself.
52
53 --output-item-list output-item-list-file.
54 The optional path to a newline-separated config file that specifies the
55 file patterns to copy into the --output-dir. Required if providing
56 the --output-dir flag.
Daniel Normana4911da2019-03-15 14:36:21 -070057
Daniel Norman3b64ce12019-04-16 16:11:35 -070058 --output-ota output-ota-package
59 The output ota package. This is a zip archive. Use of this flag may
60 require passing the --path common flag; see common.py.
61
Daniel Norman1bd2a1d2019-04-18 12:32:18 -070062 --output-img output-img-package
63 The output img package, suitable for use with 'fastboot update'. Use of
64 this flag may require passing the --path common flag; see common.py.
65
Daniel Normanf0318252019-04-15 11:34:56 -070066 --output-super-empty output-super-empty-image
67 If provided, creates a super_empty.img file from the merged target
68 files package and saves it at this path.
69
Daniel Normana4911da2019-03-15 14:36:21 -070070 --rebuild_recovery
Bill Peckhame868aec2019-09-17 17:06:47 -070071 Deprecated; does nothing.
Bill Peckham364c1cc2019-03-29 18:27:23 -070072
73 --keep-tmp
74 Keep tempoary files for debugging purposes.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080075"""
76
77from __future__ import print_function
78
Bill Peckhame9eb5f92019-02-01 15:52:10 -080079import fnmatch
80import logging
81import os
Bill Peckham19c3feb2020-03-20 18:31:43 -070082import re
Daniel Normanfdb38812019-04-15 09:47:24 -070083import shutil
Bill Peckham540d91a2019-04-25 14:18:16 -070084import subprocess
Bill Peckhame9eb5f92019-02-01 15:52:10 -080085import sys
86import zipfile
87
Bill Peckhame9eb5f92019-02-01 15:52:10 -080088import add_img_to_target_files
Daniel Normanf0318252019-04-15 11:34:56 -070089import build_super_image
Yifan Hongade0d3f2019-08-21 16:37:11 -070090import check_target_files_vintf
Daniel Normanf0318252019-04-15 11:34:56 -070091import common
Daniel Norman1bd2a1d2019-04-18 12:32:18 -070092import img_from_target_files
Daniel Norman3b64ce12019-04-16 16:11:35 -070093import ota_from_target_files
Bill Peckhame9eb5f92019-02-01 15:52:10 -080094
95logger = logging.getLogger(__name__)
Tao Bao2ad4b822019-06-27 16:52:12 -070096
Bill Peckhame9eb5f92019-02-01 15:52:10 -080097OPTIONS = common.OPTIONS
Bill Peckhamcb848172020-04-03 12:50:47 -070098# Always turn on verbose logging.
99OPTIONS.verbose = True
Daniel Normand5d70ea2019-06-05 15:13:43 -0700100OPTIONS.framework_target_files = None
101OPTIONS.framework_item_list = None
102OPTIONS.framework_misc_info_keys = None
103OPTIONS.vendor_target_files = None
104OPTIONS.vendor_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -0800105OPTIONS.output_target_files = None
Daniel Normanfdb38812019-04-15 09:47:24 -0700106OPTIONS.output_dir = None
107OPTIONS.output_item_list = None
Daniel Norman3b64ce12019-04-16 16:11:35 -0700108OPTIONS.output_ota = None
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700109OPTIONS.output_img = None
Daniel Normanf0318252019-04-15 11:34:56 -0700110OPTIONS.output_super_empty = None
Bill Peckhame868aec2019-09-17 17:06:47 -0700111# TODO(b/132730255): Remove this option.
Daniel Normana4911da2019-03-15 14:36:21 -0700112OPTIONS.rebuild_recovery = False
Bill Peckhamf753e152019-02-19 18:02:46 -0800113OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800114
Bill Peckham19c3feb2020-03-20 18:31:43 -0700115# In an item list (framework or vendor), we may see entries that select whole
116# partitions. Such an entry might look like this 'SYSTEM/*' (e.g., for the
117# system partition). The following regex matches this and extracts the
118# partition name.
119
120PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/\*$')
121
Bill Peckham5c7b0342020-04-03 15:36:23 -0700122# In apexkeys.txt or apkcerts.txt, we will find partition tags on each entry in
123# the file. We use these partition tags to filter the entries in those files
124# from the two different target files packages to produce a merged apexkeys.txt
125# or apkcerts.txt file. A partition tag (e.g., for the product partition) looks
126# like this: 'partition="product"'. We use the group syntax grab the value of
127# the tag. We use non-greedy matching in case there are other fields on the
128# same line.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700129
Bill Peckham5c7b0342020-04-03 15:36:23 -0700130PARTITION_TAG_PATTERN = re.compile(r'partition="(.*?)"')
Bill Peckham19c3feb2020-03-20 18:31:43 -0700131
132# The sorting algorithm for apexkeys.txt and apkcerts.txt does not include the
133# ".apex" or ".apk" suffix, so we use the following pattern to extract a key.
134
135MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
136
Daniel Normand5d70ea2019-06-05 15:13:43 -0700137# DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
138# framework target files package as is, meaning these items will land in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800139# output target files package exactly as they appear in the input partial
Daniel Normand5d70ea2019-06-05 15:13:43 -0700140# framework target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800141
Daniel Normand5d70ea2019-06-05 15:13:43 -0700142DEFAULT_FRAMEWORK_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800143 'META/apkcerts.txt',
144 'META/filesystem_config.txt',
145 'META/root_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800146 'META/update_engine_config.txt',
147 'PRODUCT/*',
148 'ROOT/*',
149 'SYSTEM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700150)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800151
Daniel Normand5d70ea2019-06-05 15:13:43 -0700152# FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
153# partial framework target files package that need some special processing, such
154# as some sort of combination with items from the partial vendor target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800155# package.
156
Daniel Normand5d70ea2019-06-05 15:13:43 -0700157FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800158
Daniel Normand5d70ea2019-06-05 15:13:43 -0700159# DEFAULT_FRAMEWORK_MISC_INFO_KEYS is a list of keys to obtain from the
160# framework instance of META/misc_info.txt. The remaining keys from the
161# vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800162
Daniel Normand5d70ea2019-06-05 15:13:43 -0700163DEFAULT_FRAMEWORK_MISC_INFO_KEYS = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800164 'avb_system_hashtree_enable',
165 'avb_system_add_hashtree_footer_args',
166 'avb_system_key_path',
167 'avb_system_algorithm',
168 'avb_system_rollback_index_location',
169 'avb_product_hashtree_enable',
170 'avb_product_add_hashtree_footer_args',
Justin Yun6151e3f2019-06-25 15:58:13 +0900171 'avb_system_ext_hashtree_enable',
172 'avb_system_ext_add_hashtree_footer_args',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800173 'system_root_image',
174 'root_dir',
175 'ab_update',
176 'default_system_dev_certificate',
177 'system_size',
Chris Gross203191b2020-05-30 02:39:12 +0000178 'building_system_image',
179 'building_system_ext_image',
180 'building_product_image',
Daniel Normanedf12472019-05-22 10:47:08 -0700181)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800182
Daniel Normand5d70ea2019-06-05 15:13:43 -0700183# DEFAULT_VENDOR_ITEM_LIST is a list of items to extract from the partial
184# vendor target files package as is, meaning these items will land in the output
185# target files package exactly as they appear in the input partial vendor target
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800186# files package.
187
Daniel Normand5d70ea2019-06-05 15:13:43 -0700188DEFAULT_VENDOR_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800189 'META/boot_filesystem_config.txt',
190 'META/otakeys.txt',
191 'META/releasetools.py',
192 'META/vendor_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800193 'BOOT/*',
194 'DATA/*',
195 'ODM/*',
196 'OTA/android-info.txt',
197 'PREBUILT_IMAGES/*',
198 'RADIO/*',
199 'VENDOR/*',
Yifan Hongcfb917a2020-05-07 14:58:20 -0700200 'VENDOR_DLKM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700201)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800202
Daniel Normand5d70ea2019-06-05 15:13:43 -0700203# VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
204# partial vendor target files package that need some special processing, such as
205# some sort of combination with items from the partial framework target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800206# package.
207
Daniel Normand5d70ea2019-06-05 15:13:43 -0700208VENDOR_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Daniel Normanedf12472019-05-22 10:47:08 -0700209
210# The merge config lists should not attempt to extract items from both
211# builds for any of the following partitions. The partitions in
212# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700213# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700214
215SINGLE_BUILD_PARTITIONS = (
216 'BOOT/',
217 'DATA/',
218 'ODM/',
219 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900220 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700221 'RADIO/',
222 'RECOVERY/',
223 'ROOT/',
224 'SYSTEM/',
225 'SYSTEM_OTHER/',
226 'VENDOR/',
Yifan Hongcfb917a2020-05-07 14:58:20 -0700227 'VENDOR_DLKM/',
Daniel Normanedf12472019-05-22 10:47:08 -0700228)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800229
230
Chris Grossfabf50a2019-05-02 12:42:09 -0700231def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700232 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700233
Tao Bao2ad4b822019-06-27 16:52:12 -0700234 This function sorts the contents of the list or dict and then writes the
235 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700236
237 Args:
238 data: The list or dict to sort and write.
239 path: Path to the file to write the sorted values to. The file at path will
240 be overridden if it exists.
241 """
242 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700243 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700244 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
245 data, dict) else '{}\n'.format(entry)
246 output.write(out_str)
247
248
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800249def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700250 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800251
252 This function extracts from the specified target files zip archive into the
253 specified temporary directory, the items specified in the extract item list.
254
255 Args:
256 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800257 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700258 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800259 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800260 """
261
262 logger.info('extracting from %s', target_files)
263
264 # Filter the extract_item_list to remove any items that do not exist in the
265 # zip file. Otherwise, the extraction step will fail.
266
Daniel Norman4cc9df62019-07-18 10:11:07 -0700267 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800268 target_files_namelist = target_files_zipfile.namelist()
269
270 filtered_extract_item_list = []
271 for pattern in extract_item_list:
272 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
273 if not matching_namelist:
274 logger.warning('no match for %s', pattern)
275 else:
276 filtered_extract_item_list.append(pattern)
277
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800278 # Extract from target_files into target_files_temp_dir the
279 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800280
Daniel Normane5b134a2019-04-17 14:54:06 -0700281 common.UnzipToDir(target_files, target_files_temp_dir,
282 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800283
284
Daniel Normanfdb38812019-04-15 09:47:24 -0700285def copy_items(from_dir, to_dir, patterns):
286 """Similar to extract_items() except uses an input dir instead of zip."""
287 file_paths = []
288 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700289 file_paths.extend(
290 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
291 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700292
293 filtered_file_paths = set()
294 for pattern in patterns:
295 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
296
297 for file_path in filtered_file_paths:
298 original_file_path = os.path.join(from_dir, file_path)
299 copied_file_path = os.path.join(to_dir, file_path)
300 copied_file_dir = os.path.dirname(copied_file_path)
301 if not os.path.exists(copied_file_dir):
302 os.makedirs(copied_file_dir)
303 if os.path.islink(original_file_path):
304 os.symlink(os.readlink(original_file_path), copied_file_path)
305 else:
306 shutil.copyfile(original_file_path, copied_file_path)
307
308
Daniel Normand5d70ea2019-06-05 15:13:43 -0700309def validate_config_lists(framework_item_list, framework_misc_info_keys,
310 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700311 """Performs validations on the merge config lists.
312
313 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700314 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700315 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700316 framework_misc_info_keys: A list of keys to obtain from the framework
317 instance of META/misc_info.txt. The remaining keys from the vendor
318 instance.
319 vendor_item_list: The list of items to extract from the partial vendor
320 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700321
322 Returns:
323 False if a validation fails, otherwise true.
324 """
Daniel Normanedf12472019-05-22 10:47:08 -0700325 has_error = False
326
Daniel Normand5d70ea2019-06-05 15:13:43 -0700327 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
328 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700329
Daniel Normand5d70ea2019-06-05 15:13:43 -0700330 combined_item_set = set(framework_item_list)
331 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700332
333 # Check that the merge config lists are not missing any item specified
334 # by the default config lists.
335 difference = default_combined_item_set.difference(combined_item_set)
336 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700337 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700338 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700339 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700340 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700341 has_error = True
342
343 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700344 in_framework = any(
345 item.startswith(partition) for item in framework_item_list)
346 in_vendor = any(item.startswith(partition) for item in vendor_item_list)
347 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700348 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700349 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900350 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700351 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700352 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700353
Daniel Normand5d70ea2019-06-05 15:13:43 -0700354 if ('dynamic_partition_list' in framework_misc_info_keys) or (
355 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700356 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700357 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700358 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700359
Daniel Normanedf12472019-05-22 10:47:08 -0700360 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700361
362
Daniel Normand5d70ea2019-06-05 15:13:43 -0700363def process_ab_partitions_txt(framework_target_files_temp_dir,
364 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700365 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700366 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800367
Tao Bao2ad4b822019-06-27 16:52:12 -0700368 This function merges the contents of the META/ab_partitions.txt files from the
369 framework directory and the vendor directory, placing the merged result in the
370 output directory. The precondition in that the files are already extracted.
371 The post condition is that the output META/ab_partitions.txt contains the
372 merged content. The format for each ab_partitions.txt a one partition name per
373 line. The output file contains the union of the parition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800374
375 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700376 framework_target_files_temp_dir: The name of a directory containing the
377 special items extracted from the framework target files package.
378 vendor_target_files_temp_dir: The name of a directory containing the special
379 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700380 output_target_files_temp_dir: The name of a directory that will be used to
381 create the output target files package after all the special cases are
382 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800383 """
384
Daniel Normand5d70ea2019-06-05 15:13:43 -0700385 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
386 'META', 'ab_partitions.txt')
387
388 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700389 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800390
Daniel Normand5d70ea2019-06-05 15:13:43 -0700391 with open(framework_ab_partitions_txt) as f:
392 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800393
Daniel Normand5d70ea2019-06-05 15:13:43 -0700394 with open(vendor_ab_partitions_txt) as f:
395 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800396
Daniel Normand5d70ea2019-06-05 15:13:43 -0700397 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800398
Daniel Normane5b134a2019-04-17 14:54:06 -0700399 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
400 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800401
Chris Grossfabf50a2019-05-02 12:42:09 -0700402 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800403
404
Daniel Normand5d70ea2019-06-05 15:13:43 -0700405def process_misc_info_txt(framework_target_files_temp_dir,
406 vendor_target_files_temp_dir,
407 output_target_files_temp_dir,
408 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700409 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800410
411 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700412 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800413 output directory. The precondition in that the files are already extracted.
414 The post condition is that the output META/misc_info.txt contains the merged
415 content.
416
417 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700418 framework_target_files_temp_dir: The name of a directory containing the
419 special items extracted from the framework target files package.
420 vendor_target_files_temp_dir: The name of a directory containing the special
421 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700422 output_target_files_temp_dir: The name of a directory that will be used to
423 create the output target files package after all the special cases are
424 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700425 framework_misc_info_keys: A list of keys to obtain from the framework
426 instance of META/misc_info.txt. The remaining keys from the vendor
427 instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800428 """
429
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900430 misc_info_path = ['META', 'misc_info.txt']
431 framework_dict = common.LoadDictionaryFromFile(
432 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800433
Daniel Normand5d70ea2019-06-05 15:13:43 -0700434 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800435
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900436 merged_dict = common.LoadDictionaryFromFile(
437 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800438
Daniel Normand5d70ea2019-06-05 15:13:43 -0700439 # Replace certain values in merged_dict with values from
440 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800441
Daniel Normand5d70ea2019-06-05 15:13:43 -0700442 for key in framework_misc_info_keys:
443 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800444
Daniel Norman19b9fe92019-03-19 14:48:02 -0700445 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700446 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
447 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700448 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Norman55417142019-11-25 16:04:36 -0800449 framework_dict=framework_dict, vendor_dict=merged_dict)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700450 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700451 # Ensure that add_img_to_target_files rebuilds super split images for
452 # devices that retrofit dynamic partitions. This flag may have been set to
453 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700454 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700455
Daniel Normand5d70ea2019-06-05 15:13:43 -0700456 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700457 # depending on which dictionary the key came from.
458 # Only the file basename is required because all selinux_fc properties are
459 # replaced with the full path to the file under META/ when misc_info.txt is
460 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700461 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700462 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700463 merged_dict[key] = 'vendor_file_contexts.bin'
464 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700465 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700466 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700467
Daniel Normane5b134a2019-04-17 14:54:06 -0700468 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
469 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700470 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800471
472
Daniel Normand5d70ea2019-06-05 15:13:43 -0700473def process_dynamic_partitions_info_txt(framework_target_files_dir,
474 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700475 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700476 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700477
478 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700479 files from the framework directory and the vendor directory, placing the
480 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700481
Daniel Normand5d70ea2019-06-05 15:13:43 -0700482 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700483 directory does not exist.
484
485 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700486 framework_target_files_dir: The name of a directory containing the special
487 items extracted from the framework target files package.
488 vendor_target_files_dir: The name of a directory containing the special
489 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700490 output_target_files_dir: The name of a directory that will be used to create
491 the output target files package after all the special cases are processed.
492 """
493
494 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700495 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700496 'dynamic_partitions_info.txt')):
497 return
498
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900499 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700500
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900501 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
502 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
503 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
504 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700505
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700506 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700507 framework_dict=framework_dynamic_partitions_dict,
Daniel Norman55417142019-11-25 16:04:36 -0800508 vendor_dict=vendor_dynamic_partitions_dict)
Daniel Normana61cde02019-05-03 14:19:13 -0700509
510 output_dynamic_partitions_info_txt = os.path.join(
511 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700512 write_sorted_data(
513 data=merged_dynamic_partitions_dict,
514 path=output_dynamic_partitions_info_txt)
515
516
Bill Peckham19c3feb2020-03-20 18:31:43 -0700517def item_list_to_partition_set(item_list):
518 """Converts a target files item list to a partition set.
519
520 The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
521 'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
522 directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
523 contents of a partition of the same name. Other items in the list, such as the
524 'OTA' example contain metadata. This function iterates such a list, returning
525 a set that contains the partition entries.
526
527 Args:
528 item_list: A list of items in a target files package.
529 Returns:
530 A set of partitions extracted from the list of items.
531 """
532
533 partition_set = set()
534
535 for item in item_list:
536 match = PARTITION_ITEM_PATTERN.search(item.strip())
537 partition_tag = match.group(1).lower() if match else None
538
539 if partition_tag:
540 partition_set.add(partition_tag)
541
542 return partition_set
543
544
Daniel Normand5d70ea2019-06-05 15:13:43 -0700545def process_apex_keys_apk_certs_common(framework_target_files_dir,
546 vendor_target_files_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700547 output_target_files_dir,
548 framework_partition_set,
549 vendor_partition_set, file_name):
550
Tao Bao2ad4b822019-06-27 16:52:12 -0700551 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700552
553 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700554 META/apkcerts.txt files from the framework directory and the vendor directory,
555 placing the merged result in the output directory. The precondition in that
556 the files are already extracted. The post condition is that the output
557 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700558
559 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700560 framework_target_files_dir: The name of a directory containing the special
561 items extracted from the framework target files package.
562 vendor_target_files_dir: The name of a directory containing the special
563 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700564 output_target_files_dir: The name of a directory that will be used to create
565 the output target files package after all the special cases are processed.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700566 framework_partition_set: Partitions that are considered framework
567 partitions. Used to filter apexkeys.txt and apkcerts.txt.
568 vendor_partition_set: Partitions that are considered vendor partitions. Used
569 to filter apexkeys.txt and apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700570 file_name: The name of the file to merge. One of apkcerts.txt or
571 apexkeys.txt.
572 """
573
574 def read_helper(d):
575 temp = {}
576 file_path = os.path.join(d, 'META', file_name)
577 with open(file_path) as f:
578 for line in f:
579 if line.strip():
Bill Peckham19c3feb2020-03-20 18:31:43 -0700580 name = line.split()[0]
581 match = MODULE_KEY_PATTERN.search(name)
582 temp[match.group(1)] = line.strip()
Chris Grossfabf50a2019-05-02 12:42:09 -0700583 return temp
584
Daniel Normand5d70ea2019-06-05 15:13:43 -0700585 framework_dict = read_helper(framework_target_files_dir)
586 vendor_dict = read_helper(vendor_target_files_dir)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700587 merged_dict = {}
Chris Grossfabf50a2019-05-02 12:42:09 -0700588
Bill Peckham19c3feb2020-03-20 18:31:43 -0700589 def filter_into_merged_dict(item_dict, partition_set):
590 for key, value in item_dict.items():
591 match = PARTITION_TAG_PATTERN.search(value)
592
593 if match is None:
594 raise ValueError('Entry missing partition tag: %s' % value)
595
596 partition_tag = match.group(1)
597
598 if partition_tag in partition_set:
599 if key in merged_dict:
600 raise ValueError('Duplicate key %s' % key)
601
602 merged_dict[key] = value
603
604 filter_into_merged_dict(framework_dict, framework_partition_set)
605 filter_into_merged_dict(vendor_dict, vendor_partition_set)
Chris Grossfabf50a2019-05-02 12:42:09 -0700606
607 output_file = os.path.join(output_target_files_dir, 'META', file_name)
608
Bill Peckham19c3feb2020-03-20 18:31:43 -0700609 # The following code is similar to write_sorted_data, but different enough
610 # that we couldn't use that function. We need the output to be sorted by the
611 # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
612 # allows the sort to be consistent with the framework/vendor input data and
613 # eases comparison of input data with merged data.
614 with open(output_file, 'w') as output:
615 for key in sorted(merged_dict.keys()):
616 out_str = merged_dict[key] + '\n'
617 output.write(out_str)
Daniel Normana61cde02019-05-03 14:19:13 -0700618
619
Daniel Normand5d70ea2019-06-05 15:13:43 -0700620def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700621 output_target_files_dir):
622 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700623 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
624 'framework_file_contexts.bin')
625 if not os.path.exists(framework_fc_path):
626 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
627 'file_contexts.bin')
628 if not os.path.exists(framework_fc_path):
629 raise ValueError('Missing framework file_contexts.bin.')
630 shutil.copyfile(
631 framework_fc_path,
632 os.path.join(output_target_files_dir, 'META',
633 'framework_file_contexts.bin'))
634
635 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
636 'vendor_file_contexts.bin')
637 if not os.path.exists(vendor_fc_path):
638 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700639 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700640 if not os.path.exists(vendor_fc_path):
641 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700642 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700643 vendor_fc_path,
644 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700645
646
Daniel Normand5d70ea2019-06-05 15:13:43 -0700647def process_special_cases(framework_target_files_temp_dir,
648 vendor_target_files_temp_dir,
649 output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700650 framework_misc_info_keys,
651 framework_partition_set,
652 vendor_partition_set):
Tao Bao2ad4b822019-06-27 16:52:12 -0700653 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800654
655 Certain files in the output target files package require special-case
656 processing. This function performs all that special-case processing.
657
658 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700659 framework_target_files_temp_dir: The name of a directory containing the
660 special items extracted from the framework target files package.
661 vendor_target_files_temp_dir: The name of a directory containing the special
662 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700663 output_target_files_temp_dir: The name of a directory that will be used to
664 create the output target files package after all the special cases are
665 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700666 framework_misc_info_keys: A list of keys to obtain from the framework
667 instance of META/misc_info.txt. The remaining keys from the vendor
668 instance.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700669 framework_partition_set: Partitions that are considered framework
670 partitions. Used to filter apexkeys.txt and apkcerts.txt.
671 vendor_partition_set: Partitions that are considered vendor partitions. Used
672 to filter apexkeys.txt and apkcerts.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800673 """
674
Daniel Normand5d70ea2019-06-05 15:13:43 -0700675 if 'ab_update' in framework_misc_info_keys:
Bill Peckham364c1cc2019-03-29 18:27:23 -0700676 process_ab_partitions_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700677 framework_target_files_temp_dir=framework_target_files_temp_dir,
678 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700679 output_target_files_temp_dir=output_target_files_temp_dir)
680
Daniel Norman72c626f2019-05-13 15:58:14 -0700681 copy_file_contexts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700682 framework_target_files_dir=framework_target_files_temp_dir,
683 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700684 output_target_files_dir=output_target_files_temp_dir)
685
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800686 process_misc_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700687 framework_target_files_temp_dir=framework_target_files_temp_dir,
688 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800689 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700690 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800691
Daniel Normana61cde02019-05-03 14:19:13 -0700692 process_dynamic_partitions_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700693 framework_target_files_dir=framework_target_files_temp_dir,
694 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman714bd122019-05-08 16:20:02 -0700695 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700696
Chris Grossfabf50a2019-05-02 12:42:09 -0700697 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700698 framework_target_files_dir=framework_target_files_temp_dir,
699 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700700 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700701 framework_partition_set=framework_partition_set,
702 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700703 file_name='apkcerts.txt')
704
705 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700706 framework_target_files_dir=framework_target_files_temp_dir,
707 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700708 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700709 framework_partition_set=framework_partition_set,
710 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700711 file_name='apexkeys.txt')
712
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800713
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900714def files_from_path(target_path, extra_args=None):
Tao Bao2ad4b822019-06-27 16:52:12 -0700715 """Gets files under given path.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800716
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900717 Get (sub)files from given target path and return sorted list.
718
719 Args:
720 target_path: Target path to get subfiles.
721 extra_args: List of extra argument for find command. Optional.
722
723 Returns:
724 Sorted files and directories list.
725 """
726
727 find_command = ['find', target_path] + (extra_args or [])
728 find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700729 return common.RunAndCheckOutput(['sort'],
730 stdin=find_process.stdout,
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900731 verbose=False)
732
733
734def create_merged_package(temp_dir, framework_target_files, framework_item_list,
735 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700736 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700737 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800738
739 Args:
740 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700741 input target files packages, and also a scratch directory that we use for
742 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700743 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700744 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700745 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700746 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700747 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700748 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700749 vendor_target_files: The name of the zip archive containing the vendor
750 partial target files package.
751 vendor_item_list: The list of items to extract from the partial vendor
752 target files package as is, meaning these items will land in the output
753 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700754 target files package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900755 framework_misc_info_keys: The list of keys to obtain from the framework
756 instance of META/misc_info.txt. The remaining keys from the vendor
757 instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700758 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700759 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800760
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900761 Returns:
762 Path to merged package under temp directory.
763 """
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800764
Daniel Normand5d70ea2019-06-05 15:13:43 -0700765 # Create directory names that we'll use when we extract files from framework,
766 # and vendor, and for zipping the final output.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800767
Daniel Normand5d70ea2019-06-05 15:13:43 -0700768 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
769 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800770 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
771
Daniel Normand5d70ea2019-06-05 15:13:43 -0700772 # Extract "as is" items from the input framework partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800773 # We extract them directly into the output temporary directory since the
774 # items do not need special case processing.
775
Bill Peckham889b0c62019-02-21 18:53:37 -0800776 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700777 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800778 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700779 extract_item_list=framework_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800780
Daniel Normand5d70ea2019-06-05 15:13:43 -0700781 # Extract "as is" items from the input vendor partial target files package. We
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800782 # extract them directly into the output temporary directory since the items
783 # do not need special case processing.
784
Bill Peckham889b0c62019-02-21 18:53:37 -0800785 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700786 target_files=vendor_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800787 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700788 extract_item_list=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800789
Daniel Normand5d70ea2019-06-05 15:13:43 -0700790 # Extract "special" items from the input framework partial target files
791 # package. We extract these items to different directory since they require
792 # special processing before they will end up in the output directory.
793
794 extract_items(
795 target_files=framework_target_files,
796 target_files_temp_dir=framework_target_files_temp_dir,
797 extract_item_list=FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST)
798
799 # Extract "special" items from the input vendor partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800800 # We extract these items to different directory since they require special
801 # processing before they will end up in the output directory.
802
Bill Peckham889b0c62019-02-21 18:53:37 -0800803 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700804 target_files=vendor_target_files,
805 target_files_temp_dir=vendor_target_files_temp_dir,
806 extract_item_list=VENDOR_EXTRACT_SPECIAL_ITEM_LIST)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800807
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800808 # Now that the temporary directories contain all the extracted files, perform
809 # special case processing on any items that need it. After this function
810 # completes successfully, all the files we need to create the output target
811 # files package are in place.
812
Bill Peckham889b0c62019-02-21 18:53:37 -0800813 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700814 framework_target_files_temp_dir=framework_target_files_temp_dir,
815 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800816 output_target_files_temp_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700817 framework_misc_info_keys=framework_misc_info_keys,
818 framework_partition_set=item_list_to_partition_set(framework_item_list),
819 vendor_partition_set=item_list_to_partition_set(vendor_item_list))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800820
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900821 return output_target_files_temp_dir
822
823
824def generate_images(target_files_dir, rebuild_recovery):
825 """Generate images from target files.
826
827 This function takes merged output temporary directory and create images
828 from it.
829
830 Args:
831 target_files_dir: Path to merged temp directory.
832 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
833 devices and write it to the system image.
834 """
835
836 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800837
Daniel Normana4911da2019-03-15 14:36:21 -0700838 add_img_args = ['--verbose']
Paul Trautrimbc3600c2019-08-13 18:07:03 +0900839 add_img_args.append('--add_missing')
Bill Peckhame868aec2019-09-17 17:06:47 -0700840 # TODO(b/132730255): Remove this if statement.
Daniel Normana4911da2019-03-15 14:36:21 -0700841 if rebuild_recovery:
842 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900843 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800844
845 add_img_to_target_files.main(add_img_args)
846
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900847
848def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700849 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900850
851 Args:
852 target_dir: Path to the target file package which contains misc_info.txt for
853 detailed information for super image.
854 output_super_empty: If provided, copies a super_empty.img file from the
855 target files package to this path.
856 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700857 # Create super_empty.img using the merged misc_info.txt.
858
Daniel Norman4cc9df62019-07-18 10:11:07 -0700859 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700860
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900861 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
862 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700863
864 if use_dynamic_partitions != 'true' and output_super_empty:
865 raise ValueError(
866 'Building super_empty.img requires use_dynamic_partitions=true.')
867 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700868 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700869 build_super_image_args = [
870 misc_info_txt,
871 super_empty_img,
872 ]
873 build_super_image.main(build_super_image_args)
874
875 # Copy super_empty.img to the user-provided output_super_empty location.
876 if output_super_empty:
877 shutil.copyfile(super_empty_img, output_super_empty)
878
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700879
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900880def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700881 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900882
883 Args:
884 output_file: The name of the zip archive target files package.
885 source_dir: The target directory contains package to be archived.
886 temp_dir: Path to temporary directory for any intermediate files.
887 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800888 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900889 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700890 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800891
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900892 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700893 other_content = files_from_path(
894 source_dir,
895 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800896
Tao Bao2ad4b822019-06-27 16:52:12 -0700897 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800898 f.write(meta_content)
899 f.write(other_content)
900
901 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800902 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800903 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700904 '-o',
905 output_zip,
906 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900907 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700908 '-l',
909 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800910 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900911
912 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800913 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900914 logger.info('finished creating %s', output_file)
915
916 return output_zip
917
918
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900919def merge_target_files(temp_dir, framework_target_files, framework_item_list,
920 framework_misc_info_keys, vendor_target_files,
921 vendor_item_list, output_target_files, output_dir,
922 output_item_list, output_ota, output_img,
923 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700924 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900925
926 This function takes framework and vendor target files packages as input,
927 performs various file extractions, special case processing, and finally
928 creates a merged zip archive as output.
929
930 Args:
931 temp_dir: The name of a directory we use when we extract items from the
932 input target files packages, and also a scratch directory that we use for
933 temporary files.
934 framework_target_files: The name of the zip archive containing the framework
935 partial target files package.
936 framework_item_list: The list of items to extract from the partial framework
937 target files package as is, meaning these items will land in the output
938 target files package exactly as they appear in the input partial framework
939 target files package.
940 framework_misc_info_keys: The list of keys to obtain from the framework
941 instance of META/misc_info.txt. The remaining keys from the vendor
942 instance.
943 vendor_target_files: The name of the zip archive containing the vendor
944 partial target files package.
945 vendor_item_list: The list of items to extract from the partial vendor
946 target files package as is, meaning these items will land in the output
947 target files package exactly as they appear in the input partial vendor
948 target files package.
949 output_target_files: The name of the output zip archive target files package
950 created by merging framework and vendor.
951 output_dir: The destination directory for saving merged files.
952 output_item_list: The list of items to copy into the output_dir.
953 output_ota: The name of the output zip archive ota package.
954 output_img: The name of the output zip archive img package.
955 output_super_empty: If provided, creates a super_empty.img file from the
956 merged target files package and saves it at this path.
957 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
958 devices and write it to the system image.
959 """
960
961 logger.info('starting: merge framework %s and vendor %s into output %s',
962 framework_target_files, vendor_target_files, output_target_files)
963
964 output_target_files_temp_dir = create_merged_package(
965 temp_dir, framework_target_files, framework_item_list,
966 vendor_target_files, vendor_item_list, framework_misc_info_keys,
967 rebuild_recovery)
968
Yifan Hongade0d3f2019-08-21 16:37:11 -0700969 if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
970 raise RuntimeError("Incompatible VINTF metadata")
971
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900972 generate_images(output_target_files_temp_dir, rebuild_recovery)
973
974 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
975
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900976 # Finally, create the output target files zip archive and/or copy the
977 # output items to the output target files directory.
978
979 if output_dir:
980 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
981
982 if not output_target_files:
983 return
984
985 output_zip = create_target_files_archive(output_target_files,
986 output_target_files_temp_dir,
987 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800988
Daniel Norman74eb74b2019-09-18 14:01:48 -0700989 # Create the IMG package from the merged target files package.
990
991 if output_img:
992 img_from_target_files.main([output_zip, output_img])
993
Daniel Norman3b64ce12019-04-16 16:11:35 -0700994 # Create the OTA package from the merged target files package.
995
996 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700997 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -0700998
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700999
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001000def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -07001001 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001002
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001003 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001004 directory. It also cleans up the temporary directory.
1005
1006 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -07001007 func: The function to call. Should accept one parameter, the path to the
1008 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001009 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001010 """
1011
1012 # Create a temporary directory. This will serve as the parent of directories
1013 # we use when we extract items from the input target files packages, and also
1014 # a scratch directory that we use for temporary files.
1015
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001016 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
1017
1018 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001019 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001020 finally:
1021 if keep_tmp:
1022 logger.info('keeping %s', temp_dir)
1023 else:
1024 common.Cleanup()
1025
1026
1027def main():
1028 """The main function.
1029
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001030 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001031 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001032 """
1033
1034 common.InitLogging()
1035
Bill Peckhamf753e152019-02-19 18:02:46 -08001036 def option_handler(o, a):
1037 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001038 logger.warning(
1039 '--system-target-files has been renamed to --framework-target-files')
1040 OPTIONS.framework_target_files = a
1041 elif o == '--framework-target-files':
1042 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001043 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001044 logger.warning(
1045 '--system-item-list has been renamed to --framework-item-list')
1046 OPTIONS.framework_item_list = a
1047 elif o == '--framework-item-list':
1048 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001049 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001050 logger.warning('--system-misc-info-keys has been renamed to '
1051 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001052 OPTIONS.framework_misc_info_keys = a
1053 elif o == '--framework-misc-info-keys':
1054 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001055 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001056 logger.warning(
1057 '--other-target-files has been renamed to --vendor-target-files')
1058 OPTIONS.vendor_target_files = a
1059 elif o == '--vendor-target-files':
1060 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001061 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001062 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1063 OPTIONS.vendor_item_list = a
1064 elif o == '--vendor-item-list':
1065 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001066 elif o == '--output-target-files':
1067 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001068 elif o == '--output-dir':
1069 OPTIONS.output_dir = a
1070 elif o == '--output-item-list':
1071 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001072 elif o == '--output-ota':
1073 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001074 elif o == '--output-img':
1075 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001076 elif o == '--output-super-empty':
1077 OPTIONS.output_super_empty = a
Bill Peckhame868aec2019-09-17 17:06:47 -07001078 elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
Daniel Normana4911da2019-03-15 14:36:21 -07001079 OPTIONS.rebuild_recovery = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001080 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001081 OPTIONS.keep_tmp = True
1082 else:
1083 return False
1084 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001085
Bill Peckhamf753e152019-02-19 18:02:46 -08001086 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001087 sys.argv[1:],
1088 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001089 extra_long_opts=[
1090 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001091 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001092 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001093 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001094 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001095 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001096 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001097 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001098 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001099 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001100 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001101 'output-dir=',
1102 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001103 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001104 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001105 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001106 'rebuild_recovery',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001107 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001108 ],
1109 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001110
Tao Bao2ad4b822019-06-27 16:52:12 -07001111 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001112 if (args or OPTIONS.framework_target_files is None or
1113 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001114 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1115 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001116 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001117 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001118
Daniel Normand5d70ea2019-06-05 15:13:43 -07001119 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001120 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001121 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001122 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001123
Daniel Normand5d70ea2019-06-05 15:13:43 -07001124 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001125 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001126 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001127 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001128 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001129
Daniel Normand5d70ea2019-06-05 15:13:43 -07001130 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001131 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001132 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001133 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001134
Daniel Normanfdb38812019-04-15 09:47:24 -07001135 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001136 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001137 else:
1138 output_item_list = None
1139
Daniel Normane5964522019-03-19 10:32:03 -07001140 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001141 framework_item_list=framework_item_list,
1142 framework_misc_info_keys=framework_misc_info_keys,
1143 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001144 sys.exit(1)
1145
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001146 call_func_with_temp_dir(
1147 lambda temp_dir: merge_target_files(
1148 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001149 framework_target_files=OPTIONS.framework_target_files,
1150 framework_item_list=framework_item_list,
1151 framework_misc_info_keys=framework_misc_info_keys,
1152 vendor_target_files=OPTIONS.vendor_target_files,
1153 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001154 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001155 output_dir=OPTIONS.output_dir,
1156 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001157 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001158 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001159 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001160 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001161
1162
1163if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001164 main()