blob: 45532f50d02365795106f49ab8428183fd861b7f [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/*',
Yifan Hongf496f1b2020-07-15 16:52:59 -0700201 'ODM_DLKM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700202)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800203
Daniel Normand5d70ea2019-06-05 15:13:43 -0700204# VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
205# partial vendor target files package that need some special processing, such as
206# some sort of combination with items from the partial framework target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800207# package.
208
Daniel Normand5d70ea2019-06-05 15:13:43 -0700209VENDOR_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Daniel Normanedf12472019-05-22 10:47:08 -0700210
211# The merge config lists should not attempt to extract items from both
212# builds for any of the following partitions. The partitions in
213# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700214# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700215
216SINGLE_BUILD_PARTITIONS = (
217 'BOOT/',
218 'DATA/',
219 'ODM/',
220 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900221 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700222 'RADIO/',
223 'RECOVERY/',
224 'ROOT/',
225 'SYSTEM/',
226 'SYSTEM_OTHER/',
227 'VENDOR/',
Yifan Hongcfb917a2020-05-07 14:58:20 -0700228 'VENDOR_DLKM/',
Yifan Hongf496f1b2020-07-15 16:52:59 -0700229 'ODM_DLKM/',
Daniel Normanedf12472019-05-22 10:47:08 -0700230)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800231
232
Chris Grossfabf50a2019-05-02 12:42:09 -0700233def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700234 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700235
Tao Bao2ad4b822019-06-27 16:52:12 -0700236 This function sorts the contents of the list or dict and then writes the
237 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700238
239 Args:
240 data: The list or dict to sort and write.
241 path: Path to the file to write the sorted values to. The file at path will
242 be overridden if it exists.
243 """
244 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700245 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700246 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
247 data, dict) else '{}\n'.format(entry)
248 output.write(out_str)
249
250
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800251def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700252 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800253
254 This function extracts from the specified target files zip archive into the
255 specified temporary directory, the items specified in the extract item list.
256
257 Args:
258 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800259 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700260 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800261 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800262 """
263
264 logger.info('extracting from %s', target_files)
265
266 # Filter the extract_item_list to remove any items that do not exist in the
267 # zip file. Otherwise, the extraction step will fail.
268
Daniel Norman4cc9df62019-07-18 10:11:07 -0700269 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800270 target_files_namelist = target_files_zipfile.namelist()
271
272 filtered_extract_item_list = []
273 for pattern in extract_item_list:
274 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
275 if not matching_namelist:
276 logger.warning('no match for %s', pattern)
277 else:
278 filtered_extract_item_list.append(pattern)
279
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800280 # Extract from target_files into target_files_temp_dir the
281 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800282
Daniel Normane5b134a2019-04-17 14:54:06 -0700283 common.UnzipToDir(target_files, target_files_temp_dir,
284 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800285
286
Daniel Normanfdb38812019-04-15 09:47:24 -0700287def copy_items(from_dir, to_dir, patterns):
288 """Similar to extract_items() except uses an input dir instead of zip."""
289 file_paths = []
290 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700291 file_paths.extend(
292 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
293 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700294
295 filtered_file_paths = set()
296 for pattern in patterns:
297 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
298
299 for file_path in filtered_file_paths:
300 original_file_path = os.path.join(from_dir, file_path)
301 copied_file_path = os.path.join(to_dir, file_path)
302 copied_file_dir = os.path.dirname(copied_file_path)
303 if not os.path.exists(copied_file_dir):
304 os.makedirs(copied_file_dir)
305 if os.path.islink(original_file_path):
306 os.symlink(os.readlink(original_file_path), copied_file_path)
307 else:
308 shutil.copyfile(original_file_path, copied_file_path)
309
310
Daniel Normand5d70ea2019-06-05 15:13:43 -0700311def validate_config_lists(framework_item_list, framework_misc_info_keys,
312 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700313 """Performs validations on the merge config lists.
314
315 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700316 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700317 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700318 framework_misc_info_keys: A list of keys to obtain from the framework
319 instance of META/misc_info.txt. The remaining keys from the vendor
320 instance.
321 vendor_item_list: The list of items to extract from the partial vendor
322 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700323
324 Returns:
325 False if a validation fails, otherwise true.
326 """
Daniel Normanedf12472019-05-22 10:47:08 -0700327 has_error = False
328
Daniel Normand5d70ea2019-06-05 15:13:43 -0700329 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
330 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700331
Daniel Normand5d70ea2019-06-05 15:13:43 -0700332 combined_item_set = set(framework_item_list)
333 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700334
335 # Check that the merge config lists are not missing any item specified
336 # by the default config lists.
337 difference = default_combined_item_set.difference(combined_item_set)
338 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700339 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700340 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700341 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700342 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700343 has_error = True
344
345 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700346 in_framework = any(
347 item.startswith(partition) for item in framework_item_list)
348 in_vendor = any(item.startswith(partition) for item in vendor_item_list)
349 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700350 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700351 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900352 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700353 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700354 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700355
Daniel Normand5d70ea2019-06-05 15:13:43 -0700356 if ('dynamic_partition_list' in framework_misc_info_keys) or (
357 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700358 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700359 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700360 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700361
Daniel Normanedf12472019-05-22 10:47:08 -0700362 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700363
364
Daniel Normand5d70ea2019-06-05 15:13:43 -0700365def process_ab_partitions_txt(framework_target_files_temp_dir,
366 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700367 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700368 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800369
Tao Bao2ad4b822019-06-27 16:52:12 -0700370 This function merges the contents of the META/ab_partitions.txt files from the
371 framework directory and the vendor directory, placing the merged result in the
372 output directory. The precondition in that the files are already extracted.
373 The post condition is that the output META/ab_partitions.txt contains the
374 merged content. The format for each ab_partitions.txt a one partition name per
375 line. The output file contains the union of the parition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800376
377 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700378 framework_target_files_temp_dir: The name of a directory containing the
379 special items extracted from the framework target files package.
380 vendor_target_files_temp_dir: The name of a directory containing the special
381 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700382 output_target_files_temp_dir: The name of a directory that will be used to
383 create the output target files package after all the special cases are
384 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800385 """
386
Daniel Normand5d70ea2019-06-05 15:13:43 -0700387 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
388 'META', 'ab_partitions.txt')
389
390 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700391 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800392
Daniel Normand5d70ea2019-06-05 15:13:43 -0700393 with open(framework_ab_partitions_txt) as f:
394 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800395
Daniel Normand5d70ea2019-06-05 15:13:43 -0700396 with open(vendor_ab_partitions_txt) as f:
397 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800398
Daniel Normand5d70ea2019-06-05 15:13:43 -0700399 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800400
Daniel Normane5b134a2019-04-17 14:54:06 -0700401 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
402 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800403
Chris Grossfabf50a2019-05-02 12:42:09 -0700404 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800405
406
Daniel Normand5d70ea2019-06-05 15:13:43 -0700407def process_misc_info_txt(framework_target_files_temp_dir,
408 vendor_target_files_temp_dir,
409 output_target_files_temp_dir,
410 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700411 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800412
413 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700414 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800415 output directory. The precondition in that the files are already extracted.
416 The post condition is that the output META/misc_info.txt contains the merged
417 content.
418
419 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700420 framework_target_files_temp_dir: The name of a directory containing the
421 special items extracted from the framework target files package.
422 vendor_target_files_temp_dir: The name of a directory containing the special
423 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700424 output_target_files_temp_dir: The name of a directory that will be used to
425 create the output target files package after all the special cases are
426 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700427 framework_misc_info_keys: A list of keys to obtain from the framework
428 instance of META/misc_info.txt. The remaining keys from the vendor
429 instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800430 """
431
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900432 misc_info_path = ['META', 'misc_info.txt']
433 framework_dict = common.LoadDictionaryFromFile(
434 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800435
Daniel Normand5d70ea2019-06-05 15:13:43 -0700436 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800437
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900438 merged_dict = common.LoadDictionaryFromFile(
439 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800440
Daniel Normand5d70ea2019-06-05 15:13:43 -0700441 # Replace certain values in merged_dict with values from
442 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800443
Daniel Normand5d70ea2019-06-05 15:13:43 -0700444 for key in framework_misc_info_keys:
445 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800446
Daniel Norman19b9fe92019-03-19 14:48:02 -0700447 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700448 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
449 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700450 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Norman55417142019-11-25 16:04:36 -0800451 framework_dict=framework_dict, vendor_dict=merged_dict)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700452 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700453 # Ensure that add_img_to_target_files rebuilds super split images for
454 # devices that retrofit dynamic partitions. This flag may have been set to
455 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700456 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700457
Daniel Normand5d70ea2019-06-05 15:13:43 -0700458 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700459 # depending on which dictionary the key came from.
460 # Only the file basename is required because all selinux_fc properties are
461 # replaced with the full path to the file under META/ when misc_info.txt is
462 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700463 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700464 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700465 merged_dict[key] = 'vendor_file_contexts.bin'
466 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700467 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700468 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700469
Daniel Normane5b134a2019-04-17 14:54:06 -0700470 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
471 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700472 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800473
474
Daniel Normand5d70ea2019-06-05 15:13:43 -0700475def process_dynamic_partitions_info_txt(framework_target_files_dir,
476 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700477 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700478 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700479
480 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700481 files from the framework directory and the vendor directory, placing the
482 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700483
Daniel Normand5d70ea2019-06-05 15:13:43 -0700484 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700485 directory does not exist.
486
487 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700488 framework_target_files_dir: The name of a directory containing the special
489 items extracted from the framework target files package.
490 vendor_target_files_dir: The name of a directory containing the special
491 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700492 output_target_files_dir: The name of a directory that will be used to create
493 the output target files package after all the special cases are processed.
494 """
495
496 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700497 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700498 'dynamic_partitions_info.txt')):
499 return
500
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900501 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700502
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900503 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
504 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
505 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
506 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700507
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700508 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700509 framework_dict=framework_dynamic_partitions_dict,
Daniel Norman55417142019-11-25 16:04:36 -0800510 vendor_dict=vendor_dynamic_partitions_dict)
Daniel Normana61cde02019-05-03 14:19:13 -0700511
512 output_dynamic_partitions_info_txt = os.path.join(
513 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700514 write_sorted_data(
515 data=merged_dynamic_partitions_dict,
516 path=output_dynamic_partitions_info_txt)
517
518
Bill Peckham19c3feb2020-03-20 18:31:43 -0700519def item_list_to_partition_set(item_list):
520 """Converts a target files item list to a partition set.
521
522 The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
523 'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
524 directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
525 contents of a partition of the same name. Other items in the list, such as the
526 'OTA' example contain metadata. This function iterates such a list, returning
527 a set that contains the partition entries.
528
529 Args:
530 item_list: A list of items in a target files package.
531 Returns:
532 A set of partitions extracted from the list of items.
533 """
534
535 partition_set = set()
536
537 for item in item_list:
538 match = PARTITION_ITEM_PATTERN.search(item.strip())
539 partition_tag = match.group(1).lower() if match else None
540
541 if partition_tag:
542 partition_set.add(partition_tag)
543
544 return partition_set
545
546
Daniel Normand5d70ea2019-06-05 15:13:43 -0700547def process_apex_keys_apk_certs_common(framework_target_files_dir,
548 vendor_target_files_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700549 output_target_files_dir,
550 framework_partition_set,
551 vendor_partition_set, file_name):
552
Tao Bao2ad4b822019-06-27 16:52:12 -0700553 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700554
555 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700556 META/apkcerts.txt files from the framework directory and the vendor directory,
557 placing the merged result in the output directory. The precondition in that
558 the files are already extracted. The post condition is that the output
559 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700560
561 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700562 framework_target_files_dir: The name of a directory containing the special
563 items extracted from the framework target files package.
564 vendor_target_files_dir: The name of a directory containing the special
565 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700566 output_target_files_dir: The name of a directory that will be used to create
567 the output target files package after all the special cases are processed.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700568 framework_partition_set: Partitions that are considered framework
569 partitions. Used to filter apexkeys.txt and apkcerts.txt.
570 vendor_partition_set: Partitions that are considered vendor partitions. Used
571 to filter apexkeys.txt and apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700572 file_name: The name of the file to merge. One of apkcerts.txt or
573 apexkeys.txt.
574 """
575
576 def read_helper(d):
577 temp = {}
578 file_path = os.path.join(d, 'META', file_name)
579 with open(file_path) as f:
580 for line in f:
581 if line.strip():
Bill Peckham19c3feb2020-03-20 18:31:43 -0700582 name = line.split()[0]
583 match = MODULE_KEY_PATTERN.search(name)
584 temp[match.group(1)] = line.strip()
Chris Grossfabf50a2019-05-02 12:42:09 -0700585 return temp
586
Daniel Normand5d70ea2019-06-05 15:13:43 -0700587 framework_dict = read_helper(framework_target_files_dir)
588 vendor_dict = read_helper(vendor_target_files_dir)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700589 merged_dict = {}
Chris Grossfabf50a2019-05-02 12:42:09 -0700590
Bill Peckham19c3feb2020-03-20 18:31:43 -0700591 def filter_into_merged_dict(item_dict, partition_set):
592 for key, value in item_dict.items():
593 match = PARTITION_TAG_PATTERN.search(value)
594
595 if match is None:
596 raise ValueError('Entry missing partition tag: %s' % value)
597
598 partition_tag = match.group(1)
599
600 if partition_tag in partition_set:
601 if key in merged_dict:
602 raise ValueError('Duplicate key %s' % key)
603
604 merged_dict[key] = value
605
606 filter_into_merged_dict(framework_dict, framework_partition_set)
607 filter_into_merged_dict(vendor_dict, vendor_partition_set)
Chris Grossfabf50a2019-05-02 12:42:09 -0700608
609 output_file = os.path.join(output_target_files_dir, 'META', file_name)
610
Bill Peckham19c3feb2020-03-20 18:31:43 -0700611 # The following code is similar to write_sorted_data, but different enough
612 # that we couldn't use that function. We need the output to be sorted by the
613 # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
614 # allows the sort to be consistent with the framework/vendor input data and
615 # eases comparison of input data with merged data.
616 with open(output_file, 'w') as output:
617 for key in sorted(merged_dict.keys()):
618 out_str = merged_dict[key] + '\n'
619 output.write(out_str)
Daniel Normana61cde02019-05-03 14:19:13 -0700620
621
Daniel Normand5d70ea2019-06-05 15:13:43 -0700622def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700623 output_target_files_dir):
624 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700625 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
626 'framework_file_contexts.bin')
627 if not os.path.exists(framework_fc_path):
628 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
629 'file_contexts.bin')
630 if not os.path.exists(framework_fc_path):
631 raise ValueError('Missing framework file_contexts.bin.')
632 shutil.copyfile(
633 framework_fc_path,
634 os.path.join(output_target_files_dir, 'META',
635 'framework_file_contexts.bin'))
636
637 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
638 'vendor_file_contexts.bin')
639 if not os.path.exists(vendor_fc_path):
640 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700641 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700642 if not os.path.exists(vendor_fc_path):
643 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700644 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700645 vendor_fc_path,
646 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700647
648
Daniel Normand5d70ea2019-06-05 15:13:43 -0700649def process_special_cases(framework_target_files_temp_dir,
650 vendor_target_files_temp_dir,
651 output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700652 framework_misc_info_keys,
653 framework_partition_set,
654 vendor_partition_set):
Tao Bao2ad4b822019-06-27 16:52:12 -0700655 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800656
657 Certain files in the output target files package require special-case
658 processing. This function performs all that special-case processing.
659
660 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700661 framework_target_files_temp_dir: The name of a directory containing the
662 special items extracted from the framework target files package.
663 vendor_target_files_temp_dir: The name of a directory containing the special
664 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700665 output_target_files_temp_dir: The name of a directory that will be used to
666 create the output target files package after all the special cases are
667 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700668 framework_misc_info_keys: A list of keys to obtain from the framework
669 instance of META/misc_info.txt. The remaining keys from the vendor
670 instance.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700671 framework_partition_set: Partitions that are considered framework
672 partitions. Used to filter apexkeys.txt and apkcerts.txt.
673 vendor_partition_set: Partitions that are considered vendor partitions. Used
674 to filter apexkeys.txt and apkcerts.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800675 """
676
Daniel Normand5d70ea2019-06-05 15:13:43 -0700677 if 'ab_update' in framework_misc_info_keys:
Bill Peckham364c1cc2019-03-29 18:27:23 -0700678 process_ab_partitions_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700679 framework_target_files_temp_dir=framework_target_files_temp_dir,
680 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700681 output_target_files_temp_dir=output_target_files_temp_dir)
682
Daniel Norman72c626f2019-05-13 15:58:14 -0700683 copy_file_contexts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700684 framework_target_files_dir=framework_target_files_temp_dir,
685 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700686 output_target_files_dir=output_target_files_temp_dir)
687
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800688 process_misc_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700689 framework_target_files_temp_dir=framework_target_files_temp_dir,
690 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800691 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700692 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800693
Daniel Normana61cde02019-05-03 14:19:13 -0700694 process_dynamic_partitions_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700695 framework_target_files_dir=framework_target_files_temp_dir,
696 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman714bd122019-05-08 16:20:02 -0700697 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700698
Chris Grossfabf50a2019-05-02 12:42:09 -0700699 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700700 framework_target_files_dir=framework_target_files_temp_dir,
701 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700702 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700703 framework_partition_set=framework_partition_set,
704 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700705 file_name='apkcerts.txt')
706
707 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700708 framework_target_files_dir=framework_target_files_temp_dir,
709 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700710 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700711 framework_partition_set=framework_partition_set,
712 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700713 file_name='apexkeys.txt')
714
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800715
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900716def files_from_path(target_path, extra_args=None):
Tao Bao2ad4b822019-06-27 16:52:12 -0700717 """Gets files under given path.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800718
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900719 Get (sub)files from given target path and return sorted list.
720
721 Args:
722 target_path: Target path to get subfiles.
723 extra_args: List of extra argument for find command. Optional.
724
725 Returns:
726 Sorted files and directories list.
727 """
728
729 find_command = ['find', target_path] + (extra_args or [])
730 find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700731 return common.RunAndCheckOutput(['sort'],
732 stdin=find_process.stdout,
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900733 verbose=False)
734
735
736def create_merged_package(temp_dir, framework_target_files, framework_item_list,
737 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700738 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700739 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800740
741 Args:
742 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700743 input target files packages, and also a scratch directory that we use for
744 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700745 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700746 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700747 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700748 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700749 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700750 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700751 vendor_target_files: The name of the zip archive containing the vendor
752 partial target files package.
753 vendor_item_list: The list of items to extract from the partial vendor
754 target files package as is, meaning these items will land in the output
755 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700756 target files package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900757 framework_misc_info_keys: The list of keys to obtain from the framework
758 instance of META/misc_info.txt. The remaining keys from the vendor
759 instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700760 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700761 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800762
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900763 Returns:
764 Path to merged package under temp directory.
765 """
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800766
Daniel Normand5d70ea2019-06-05 15:13:43 -0700767 # Create directory names that we'll use when we extract files from framework,
768 # and vendor, and for zipping the final output.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800769
Daniel Normand5d70ea2019-06-05 15:13:43 -0700770 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
771 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800772 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
773
Daniel Normand5d70ea2019-06-05 15:13:43 -0700774 # Extract "as is" items from the input framework partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800775 # We extract them directly into the output temporary directory since the
776 # items do not need special case processing.
777
Bill Peckham889b0c62019-02-21 18:53:37 -0800778 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700779 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800780 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700781 extract_item_list=framework_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800782
Daniel Normand5d70ea2019-06-05 15:13:43 -0700783 # Extract "as is" items from the input vendor partial target files package. We
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800784 # extract them directly into the output temporary directory since the items
785 # do not need special case processing.
786
Bill Peckham889b0c62019-02-21 18:53:37 -0800787 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700788 target_files=vendor_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800789 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700790 extract_item_list=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800791
Daniel Normand5d70ea2019-06-05 15:13:43 -0700792 # Extract "special" items from the input framework partial target files
793 # package. We extract these items to different directory since they require
794 # special processing before they will end up in the output directory.
795
796 extract_items(
797 target_files=framework_target_files,
798 target_files_temp_dir=framework_target_files_temp_dir,
799 extract_item_list=FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST)
800
801 # Extract "special" items from the input vendor partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800802 # We extract these items to different directory since they require special
803 # processing before they will end up in the output directory.
804
Bill Peckham889b0c62019-02-21 18:53:37 -0800805 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700806 target_files=vendor_target_files,
807 target_files_temp_dir=vendor_target_files_temp_dir,
808 extract_item_list=VENDOR_EXTRACT_SPECIAL_ITEM_LIST)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800809
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800810 # Now that the temporary directories contain all the extracted files, perform
811 # special case processing on any items that need it. After this function
812 # completes successfully, all the files we need to create the output target
813 # files package are in place.
814
Bill Peckham889b0c62019-02-21 18:53:37 -0800815 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700816 framework_target_files_temp_dir=framework_target_files_temp_dir,
817 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800818 output_target_files_temp_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700819 framework_misc_info_keys=framework_misc_info_keys,
820 framework_partition_set=item_list_to_partition_set(framework_item_list),
821 vendor_partition_set=item_list_to_partition_set(vendor_item_list))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800822
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900823 return output_target_files_temp_dir
824
825
826def generate_images(target_files_dir, rebuild_recovery):
827 """Generate images from target files.
828
829 This function takes merged output temporary directory and create images
830 from it.
831
832 Args:
833 target_files_dir: Path to merged temp directory.
834 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
835 devices and write it to the system image.
836 """
837
838 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800839
Daniel Normana4911da2019-03-15 14:36:21 -0700840 add_img_args = ['--verbose']
Paul Trautrimbc3600c2019-08-13 18:07:03 +0900841 add_img_args.append('--add_missing')
Bill Peckhame868aec2019-09-17 17:06:47 -0700842 # TODO(b/132730255): Remove this if statement.
Daniel Normana4911da2019-03-15 14:36:21 -0700843 if rebuild_recovery:
844 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900845 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800846
847 add_img_to_target_files.main(add_img_args)
848
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900849
850def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700851 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900852
853 Args:
854 target_dir: Path to the target file package which contains misc_info.txt for
855 detailed information for super image.
856 output_super_empty: If provided, copies a super_empty.img file from the
857 target files package to this path.
858 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700859 # Create super_empty.img using the merged misc_info.txt.
860
Daniel Norman4cc9df62019-07-18 10:11:07 -0700861 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700862
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900863 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
864 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700865
866 if use_dynamic_partitions != 'true' and output_super_empty:
867 raise ValueError(
868 'Building super_empty.img requires use_dynamic_partitions=true.')
869 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700870 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700871 build_super_image_args = [
872 misc_info_txt,
873 super_empty_img,
874 ]
875 build_super_image.main(build_super_image_args)
876
877 # Copy super_empty.img to the user-provided output_super_empty location.
878 if output_super_empty:
879 shutil.copyfile(super_empty_img, output_super_empty)
880
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700881
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900882def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700883 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900884
885 Args:
886 output_file: The name of the zip archive target files package.
887 source_dir: The target directory contains package to be archived.
888 temp_dir: Path to temporary directory for any intermediate files.
889 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800890 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900891 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700892 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800893
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900894 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700895 other_content = files_from_path(
896 source_dir,
897 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800898
Tao Bao2ad4b822019-06-27 16:52:12 -0700899 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800900 f.write(meta_content)
901 f.write(other_content)
902
903 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800904 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800905 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700906 '-o',
907 output_zip,
908 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900909 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700910 '-l',
911 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800912 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900913
914 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800915 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900916 logger.info('finished creating %s', output_file)
917
918 return output_zip
919
920
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900921def merge_target_files(temp_dir, framework_target_files, framework_item_list,
922 framework_misc_info_keys, vendor_target_files,
923 vendor_item_list, output_target_files, output_dir,
924 output_item_list, output_ota, output_img,
925 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700926 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900927
928 This function takes framework and vendor target files packages as input,
929 performs various file extractions, special case processing, and finally
930 creates a merged zip archive as output.
931
932 Args:
933 temp_dir: The name of a directory we use when we extract items from the
934 input target files packages, and also a scratch directory that we use for
935 temporary files.
936 framework_target_files: The name of the zip archive containing the framework
937 partial target files package.
938 framework_item_list: The list of items to extract from the partial framework
939 target files package as is, meaning these items will land in the output
940 target files package exactly as they appear in the input partial framework
941 target files package.
942 framework_misc_info_keys: The list of keys to obtain from the framework
943 instance of META/misc_info.txt. The remaining keys from the vendor
944 instance.
945 vendor_target_files: The name of the zip archive containing the vendor
946 partial target files package.
947 vendor_item_list: The list of items to extract from the partial vendor
948 target files package as is, meaning these items will land in the output
949 target files package exactly as they appear in the input partial vendor
950 target files package.
951 output_target_files: The name of the output zip archive target files package
952 created by merging framework and vendor.
953 output_dir: The destination directory for saving merged files.
954 output_item_list: The list of items to copy into the output_dir.
955 output_ota: The name of the output zip archive ota package.
956 output_img: The name of the output zip archive img package.
957 output_super_empty: If provided, creates a super_empty.img file from the
958 merged target files package and saves it at this path.
959 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
960 devices and write it to the system image.
961 """
962
963 logger.info('starting: merge framework %s and vendor %s into output %s',
964 framework_target_files, vendor_target_files, output_target_files)
965
966 output_target_files_temp_dir = create_merged_package(
967 temp_dir, framework_target_files, framework_item_list,
968 vendor_target_files, vendor_item_list, framework_misc_info_keys,
969 rebuild_recovery)
970
Yifan Hongade0d3f2019-08-21 16:37:11 -0700971 if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
972 raise RuntimeError("Incompatible VINTF metadata")
973
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900974 generate_images(output_target_files_temp_dir, rebuild_recovery)
975
976 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
977
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900978 # Finally, create the output target files zip archive and/or copy the
979 # output items to the output target files directory.
980
981 if output_dir:
982 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
983
984 if not output_target_files:
985 return
986
987 output_zip = create_target_files_archive(output_target_files,
988 output_target_files_temp_dir,
989 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800990
Daniel Norman74eb74b2019-09-18 14:01:48 -0700991 # Create the IMG package from the merged target files package.
992
993 if output_img:
994 img_from_target_files.main([output_zip, output_img])
995
Daniel Norman3b64ce12019-04-16 16:11:35 -0700996 # Create the OTA package from the merged target files package.
997
998 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700999 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -07001000
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001001
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001002def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -07001003 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001004
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001005 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001006 directory. It also cleans up the temporary directory.
1007
1008 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -07001009 func: The function to call. Should accept one parameter, the path to the
1010 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001011 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001012 """
1013
1014 # Create a temporary directory. This will serve as the parent of directories
1015 # we use when we extract items from the input target files packages, and also
1016 # a scratch directory that we use for temporary files.
1017
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001018 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
1019
1020 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001021 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001022 finally:
1023 if keep_tmp:
1024 logger.info('keeping %s', temp_dir)
1025 else:
1026 common.Cleanup()
1027
1028
1029def main():
1030 """The main function.
1031
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001032 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001033 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001034 """
1035
1036 common.InitLogging()
1037
Bill Peckhamf753e152019-02-19 18:02:46 -08001038 def option_handler(o, a):
1039 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001040 logger.warning(
1041 '--system-target-files has been renamed to --framework-target-files')
1042 OPTIONS.framework_target_files = a
1043 elif o == '--framework-target-files':
1044 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001045 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001046 logger.warning(
1047 '--system-item-list has been renamed to --framework-item-list')
1048 OPTIONS.framework_item_list = a
1049 elif o == '--framework-item-list':
1050 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001051 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001052 logger.warning('--system-misc-info-keys has been renamed to '
1053 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001054 OPTIONS.framework_misc_info_keys = a
1055 elif o == '--framework-misc-info-keys':
1056 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001057 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001058 logger.warning(
1059 '--other-target-files has been renamed to --vendor-target-files')
1060 OPTIONS.vendor_target_files = a
1061 elif o == '--vendor-target-files':
1062 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001063 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001064 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1065 OPTIONS.vendor_item_list = a
1066 elif o == '--vendor-item-list':
1067 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001068 elif o == '--output-target-files':
1069 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001070 elif o == '--output-dir':
1071 OPTIONS.output_dir = a
1072 elif o == '--output-item-list':
1073 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001074 elif o == '--output-ota':
1075 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001076 elif o == '--output-img':
1077 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001078 elif o == '--output-super-empty':
1079 OPTIONS.output_super_empty = a
Bill Peckhame868aec2019-09-17 17:06:47 -07001080 elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
Daniel Normana4911da2019-03-15 14:36:21 -07001081 OPTIONS.rebuild_recovery = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001082 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001083 OPTIONS.keep_tmp = True
1084 else:
1085 return False
1086 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001087
Bill Peckhamf753e152019-02-19 18:02:46 -08001088 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001089 sys.argv[1:],
1090 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001091 extra_long_opts=[
1092 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001093 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001094 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001095 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001096 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001097 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001098 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001099 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001100 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001101 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001102 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001103 'output-dir=',
1104 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001105 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001106 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001107 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001108 'rebuild_recovery',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001109 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001110 ],
1111 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001112
Tao Bao2ad4b822019-06-27 16:52:12 -07001113 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001114 if (args or OPTIONS.framework_target_files is None or
1115 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001116 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1117 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001118 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001119 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001120
Daniel Normand5d70ea2019-06-05 15:13:43 -07001121 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001122 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001123 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001124 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001125
Daniel Normand5d70ea2019-06-05 15:13:43 -07001126 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001127 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001128 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001129 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001130 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001131
Daniel Normand5d70ea2019-06-05 15:13:43 -07001132 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001133 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001134 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001135 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001136
Daniel Normanfdb38812019-04-15 09:47:24 -07001137 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001138 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001139 else:
1140 output_item_list = None
1141
Daniel Normane5964522019-03-19 10:32:03 -07001142 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001143 framework_item_list=framework_item_list,
1144 framework_misc_info_keys=framework_misc_info_keys,
1145 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001146 sys.exit(1)
1147
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001148 call_func_with_temp_dir(
1149 lambda temp_dir: merge_target_files(
1150 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001151 framework_target_files=OPTIONS.framework_target_files,
1152 framework_item_list=framework_item_list,
1153 framework_misc_info_keys=framework_misc_info_keys,
1154 vendor_target_files=OPTIONS.vendor_target_files,
1155 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001156 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001157 output_dir=OPTIONS.output_dir,
1158 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001159 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001160 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001161 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001162 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001163
1164
1165if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001166 main()