blob: 8e97509875cec3428b3e726d406a0158a393e476 [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
Daniel Normand5d70ea2019-06-05 15:13:43 -070098OPTIONS.framework_target_files = None
99OPTIONS.framework_item_list = None
100OPTIONS.framework_misc_info_keys = None
101OPTIONS.vendor_target_files = None
102OPTIONS.vendor_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -0800103OPTIONS.output_target_files = None
Daniel Normanfdb38812019-04-15 09:47:24 -0700104OPTIONS.output_dir = None
105OPTIONS.output_item_list = None
Daniel Norman3b64ce12019-04-16 16:11:35 -0700106OPTIONS.output_ota = None
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700107OPTIONS.output_img = None
Daniel Normanf0318252019-04-15 11:34:56 -0700108OPTIONS.output_super_empty = None
Bill Peckhame868aec2019-09-17 17:06:47 -0700109# TODO(b/132730255): Remove this option.
Daniel Normana4911da2019-03-15 14:36:21 -0700110OPTIONS.rebuild_recovery = False
Bill Peckhamf753e152019-02-19 18:02:46 -0800111OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800112
Bill Peckham19c3feb2020-03-20 18:31:43 -0700113# In an item list (framework or vendor), we may see entries that select whole
114# partitions. Such an entry might look like this 'SYSTEM/*' (e.g., for the
115# system partition). The following regex matches this and extracts the
116# partition name.
117
118PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/\*$')
119
120# In apexkeys.txt or apkcerts.txt, we may find partition tags on the various
121# entries in the file. We use these partition tags to filter the entries in
122# those files from the two different target files packages to produce a merged
123# apexkeys.txt or apkcerts.txt file. A partition tag (e.g., for the product
124# partition) looks like this: 'partition="_PRODUCT"' or 'partition="product".
125# We use the group syntax grab the value of the tag.
126
127PARTITION_TAG_PATTERN = re.compile(r'partition="(.*)"')
128
129# The sorting algorithm for apexkeys.txt and apkcerts.txt does not include the
130# ".apex" or ".apk" suffix, so we use the following pattern to extract a key.
131
132MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
133
Daniel Normand5d70ea2019-06-05 15:13:43 -0700134# DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
135# framework target files package as is, meaning these items will land in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800136# output target files package exactly as they appear in the input partial
Daniel Normand5d70ea2019-06-05 15:13:43 -0700137# framework target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800138
Daniel Normand5d70ea2019-06-05 15:13:43 -0700139DEFAULT_FRAMEWORK_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800140 'META/apkcerts.txt',
141 'META/filesystem_config.txt',
142 'META/root_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800143 'META/update_engine_config.txt',
144 'PRODUCT/*',
145 'ROOT/*',
146 'SYSTEM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700147)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800148
Daniel Normand5d70ea2019-06-05 15:13:43 -0700149# FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
150# partial framework target files package that need some special processing, such
151# as some sort of combination with items from the partial vendor target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800152# package.
153
Daniel Normand5d70ea2019-06-05 15:13:43 -0700154FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800155
Daniel Normand5d70ea2019-06-05 15:13:43 -0700156# DEFAULT_FRAMEWORK_MISC_INFO_KEYS is a list of keys to obtain from the
157# framework instance of META/misc_info.txt. The remaining keys from the
158# vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800159
Daniel Normand5d70ea2019-06-05 15:13:43 -0700160DEFAULT_FRAMEWORK_MISC_INFO_KEYS = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800161 'avb_system_hashtree_enable',
162 'avb_system_add_hashtree_footer_args',
163 'avb_system_key_path',
164 'avb_system_algorithm',
165 'avb_system_rollback_index_location',
166 'avb_product_hashtree_enable',
167 'avb_product_add_hashtree_footer_args',
Justin Yun6151e3f2019-06-25 15:58:13 +0900168 'avb_system_ext_hashtree_enable',
169 'avb_system_ext_add_hashtree_footer_args',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800170 'system_root_image',
171 'root_dir',
172 'ab_update',
173 'default_system_dev_certificate',
174 'system_size',
Daniel Normanedf12472019-05-22 10:47:08 -0700175)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800176
Daniel Normand5d70ea2019-06-05 15:13:43 -0700177# DEFAULT_VENDOR_ITEM_LIST is a list of items to extract from the partial
178# vendor target files package as is, meaning these items will land in the output
179# target files package exactly as they appear in the input partial vendor target
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800180# files package.
181
Daniel Normand5d70ea2019-06-05 15:13:43 -0700182DEFAULT_VENDOR_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800183 'META/boot_filesystem_config.txt',
184 'META/otakeys.txt',
185 'META/releasetools.py',
186 'META/vendor_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800187 'BOOT/*',
188 'DATA/*',
189 'ODM/*',
190 'OTA/android-info.txt',
191 'PREBUILT_IMAGES/*',
192 'RADIO/*',
193 'VENDOR/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700194)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800195
Daniel Normand5d70ea2019-06-05 15:13:43 -0700196# VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
197# partial vendor target files package that need some special processing, such as
198# some sort of combination with items from the partial framework target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800199# package.
200
Daniel Normand5d70ea2019-06-05 15:13:43 -0700201VENDOR_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Daniel Normanedf12472019-05-22 10:47:08 -0700202
203# The merge config lists should not attempt to extract items from both
204# builds for any of the following partitions. The partitions in
205# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700206# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700207
208SINGLE_BUILD_PARTITIONS = (
209 'BOOT/',
210 'DATA/',
211 'ODM/',
212 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900213 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700214 'RADIO/',
215 'RECOVERY/',
216 'ROOT/',
217 'SYSTEM/',
218 'SYSTEM_OTHER/',
219 'VENDOR/',
220)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800221
222
Chris Grossfabf50a2019-05-02 12:42:09 -0700223def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700224 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700225
Tao Bao2ad4b822019-06-27 16:52:12 -0700226 This function sorts the contents of the list or dict and then writes the
227 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700228
229 Args:
230 data: The list or dict to sort and write.
231 path: Path to the file to write the sorted values to. The file at path will
232 be overridden if it exists.
233 """
234 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700235 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700236 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
237 data, dict) else '{}\n'.format(entry)
238 output.write(out_str)
239
240
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800241def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700242 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800243
244 This function extracts from the specified target files zip archive into the
245 specified temporary directory, the items specified in the extract item list.
246
247 Args:
248 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800249 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700250 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800251 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800252 """
253
254 logger.info('extracting from %s', target_files)
255
256 # Filter the extract_item_list to remove any items that do not exist in the
257 # zip file. Otherwise, the extraction step will fail.
258
Daniel Norman4cc9df62019-07-18 10:11:07 -0700259 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800260 target_files_namelist = target_files_zipfile.namelist()
261
262 filtered_extract_item_list = []
263 for pattern in extract_item_list:
264 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
265 if not matching_namelist:
266 logger.warning('no match for %s', pattern)
267 else:
268 filtered_extract_item_list.append(pattern)
269
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800270 # Extract from target_files into target_files_temp_dir the
271 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800272
Daniel Normane5b134a2019-04-17 14:54:06 -0700273 common.UnzipToDir(target_files, target_files_temp_dir,
274 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800275
276
Daniel Normanfdb38812019-04-15 09:47:24 -0700277def copy_items(from_dir, to_dir, patterns):
278 """Similar to extract_items() except uses an input dir instead of zip."""
279 file_paths = []
280 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700281 file_paths.extend(
282 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
283 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700284
285 filtered_file_paths = set()
286 for pattern in patterns:
287 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
288
289 for file_path in filtered_file_paths:
290 original_file_path = os.path.join(from_dir, file_path)
291 copied_file_path = os.path.join(to_dir, file_path)
292 copied_file_dir = os.path.dirname(copied_file_path)
293 if not os.path.exists(copied_file_dir):
294 os.makedirs(copied_file_dir)
295 if os.path.islink(original_file_path):
296 os.symlink(os.readlink(original_file_path), copied_file_path)
297 else:
298 shutil.copyfile(original_file_path, copied_file_path)
299
300
Daniel Normand5d70ea2019-06-05 15:13:43 -0700301def validate_config_lists(framework_item_list, framework_misc_info_keys,
302 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700303 """Performs validations on the merge config lists.
304
305 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700306 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700307 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700308 framework_misc_info_keys: A list of keys to obtain from the framework
309 instance of META/misc_info.txt. The remaining keys from the vendor
310 instance.
311 vendor_item_list: The list of items to extract from the partial vendor
312 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700313
314 Returns:
315 False if a validation fails, otherwise true.
316 """
Daniel Normanedf12472019-05-22 10:47:08 -0700317 has_error = False
318
Daniel Normand5d70ea2019-06-05 15:13:43 -0700319 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
320 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700321
Daniel Normand5d70ea2019-06-05 15:13:43 -0700322 combined_item_set = set(framework_item_list)
323 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700324
325 # Check that the merge config lists are not missing any item specified
326 # by the default config lists.
327 difference = default_combined_item_set.difference(combined_item_set)
328 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700329 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700330 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700331 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700332 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700333 has_error = True
334
335 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700336 in_framework = any(
337 item.startswith(partition) for item in framework_item_list)
338 in_vendor = any(item.startswith(partition) for item in vendor_item_list)
339 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700340 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700341 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900342 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700343 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700344 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700345
Daniel Normand5d70ea2019-06-05 15:13:43 -0700346 if ('dynamic_partition_list' in framework_misc_info_keys) or (
347 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700348 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700349 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700350 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700351
Daniel Normanedf12472019-05-22 10:47:08 -0700352 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700353
354
Daniel Normand5d70ea2019-06-05 15:13:43 -0700355def process_ab_partitions_txt(framework_target_files_temp_dir,
356 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700357 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700358 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800359
Tao Bao2ad4b822019-06-27 16:52:12 -0700360 This function merges the contents of the META/ab_partitions.txt files from the
361 framework directory and the vendor directory, placing the merged result in the
362 output directory. The precondition in that the files are already extracted.
363 The post condition is that the output META/ab_partitions.txt contains the
364 merged content. The format for each ab_partitions.txt a one partition name per
365 line. The output file contains the union of the parition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800366
367 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700368 framework_target_files_temp_dir: The name of a directory containing the
369 special items extracted from the framework target files package.
370 vendor_target_files_temp_dir: The name of a directory containing the special
371 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700372 output_target_files_temp_dir: The name of a directory that will be used to
373 create the output target files package after all the special cases are
374 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800375 """
376
Daniel Normand5d70ea2019-06-05 15:13:43 -0700377 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
378 'META', 'ab_partitions.txt')
379
380 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700381 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800382
Daniel Normand5d70ea2019-06-05 15:13:43 -0700383 with open(framework_ab_partitions_txt) as f:
384 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800385
Daniel Normand5d70ea2019-06-05 15:13:43 -0700386 with open(vendor_ab_partitions_txt) as f:
387 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800388
Daniel Normand5d70ea2019-06-05 15:13:43 -0700389 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800390
Daniel Normane5b134a2019-04-17 14:54:06 -0700391 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
392 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800393
Chris Grossfabf50a2019-05-02 12:42:09 -0700394 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800395
396
Daniel Normand5d70ea2019-06-05 15:13:43 -0700397def process_misc_info_txt(framework_target_files_temp_dir,
398 vendor_target_files_temp_dir,
399 output_target_files_temp_dir,
400 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700401 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800402
403 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700404 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800405 output directory. The precondition in that the files are already extracted.
406 The post condition is that the output META/misc_info.txt contains the merged
407 content.
408
409 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700410 framework_target_files_temp_dir: The name of a directory containing the
411 special items extracted from the framework target files package.
412 vendor_target_files_temp_dir: The name of a directory containing the special
413 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700414 output_target_files_temp_dir: The name of a directory that will be used to
415 create the output target files package after all the special cases are
416 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700417 framework_misc_info_keys: A list of keys to obtain from the framework
418 instance of META/misc_info.txt. The remaining keys from the vendor
419 instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800420 """
421
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900422 misc_info_path = ['META', 'misc_info.txt']
423 framework_dict = common.LoadDictionaryFromFile(
424 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800425
Daniel Normand5d70ea2019-06-05 15:13:43 -0700426 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800427
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900428 merged_dict = common.LoadDictionaryFromFile(
429 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800430
Daniel Normand5d70ea2019-06-05 15:13:43 -0700431 # Replace certain values in merged_dict with values from
432 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800433
Daniel Normand5d70ea2019-06-05 15:13:43 -0700434 for key in framework_misc_info_keys:
435 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800436
Daniel Norman19b9fe92019-03-19 14:48:02 -0700437 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700438 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
439 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700440 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Norman55417142019-11-25 16:04:36 -0800441 framework_dict=framework_dict, vendor_dict=merged_dict)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700442 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700443 # Ensure that add_img_to_target_files rebuilds super split images for
444 # devices that retrofit dynamic partitions. This flag may have been set to
445 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700446 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700447
Daniel Normand5d70ea2019-06-05 15:13:43 -0700448 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700449 # depending on which dictionary the key came from.
450 # Only the file basename is required because all selinux_fc properties are
451 # replaced with the full path to the file under META/ when misc_info.txt is
452 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700453 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700454 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700455 merged_dict[key] = 'vendor_file_contexts.bin'
456 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700457 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700458 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700459
Daniel Normane5b134a2019-04-17 14:54:06 -0700460 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
461 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700462 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800463
464
Daniel Normand5d70ea2019-06-05 15:13:43 -0700465def process_dynamic_partitions_info_txt(framework_target_files_dir,
466 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700467 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700468 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700469
470 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700471 files from the framework directory and the vendor directory, placing the
472 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700473
Daniel Normand5d70ea2019-06-05 15:13:43 -0700474 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700475 directory does not exist.
476
477 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700478 framework_target_files_dir: The name of a directory containing the special
479 items extracted from the framework target files package.
480 vendor_target_files_dir: The name of a directory containing the special
481 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700482 output_target_files_dir: The name of a directory that will be used to create
483 the output target files package after all the special cases are processed.
484 """
485
486 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700487 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700488 'dynamic_partitions_info.txt')):
489 return
490
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900491 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700492
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900493 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
494 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
495 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
496 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700497
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700498 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700499 framework_dict=framework_dynamic_partitions_dict,
Daniel Norman55417142019-11-25 16:04:36 -0800500 vendor_dict=vendor_dynamic_partitions_dict)
Daniel Normana61cde02019-05-03 14:19:13 -0700501
502 output_dynamic_partitions_info_txt = os.path.join(
503 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700504 write_sorted_data(
505 data=merged_dynamic_partitions_dict,
506 path=output_dynamic_partitions_info_txt)
507
508
Bill Peckham19c3feb2020-03-20 18:31:43 -0700509def item_list_to_partition_set(item_list):
510 """Converts a target files item list to a partition set.
511
512 The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
513 'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
514 directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
515 contents of a partition of the same name. Other items in the list, such as the
516 'OTA' example contain metadata. This function iterates such a list, returning
517 a set that contains the partition entries.
518
519 Args:
520 item_list: A list of items in a target files package.
521 Returns:
522 A set of partitions extracted from the list of items.
523 """
524
525 partition_set = set()
526
527 for item in item_list:
528 match = PARTITION_ITEM_PATTERN.search(item.strip())
529 partition_tag = match.group(1).lower() if match else None
530
531 if partition_tag:
532 partition_set.add(partition_tag)
533
534 return partition_set
535
536
Daniel Normand5d70ea2019-06-05 15:13:43 -0700537def process_apex_keys_apk_certs_common(framework_target_files_dir,
538 vendor_target_files_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700539 output_target_files_dir,
540 framework_partition_set,
541 vendor_partition_set, file_name):
542
Tao Bao2ad4b822019-06-27 16:52:12 -0700543 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700544
545 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700546 META/apkcerts.txt files from the framework directory and the vendor directory,
547 placing the merged result in the output directory. The precondition in that
548 the files are already extracted. The post condition is that the output
549 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700550
551 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700552 framework_target_files_dir: The name of a directory containing the special
553 items extracted from the framework target files package.
554 vendor_target_files_dir: The name of a directory containing the special
555 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700556 output_target_files_dir: The name of a directory that will be used to create
557 the output target files package after all the special cases are processed.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700558 framework_partition_set: Partitions that are considered framework
559 partitions. Used to filter apexkeys.txt and apkcerts.txt.
560 vendor_partition_set: Partitions that are considered vendor partitions. Used
561 to filter apexkeys.txt and apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700562 file_name: The name of the file to merge. One of apkcerts.txt or
563 apexkeys.txt.
564 """
565
566 def read_helper(d):
567 temp = {}
568 file_path = os.path.join(d, 'META', file_name)
569 with open(file_path) as f:
570 for line in f:
571 if line.strip():
Bill Peckham19c3feb2020-03-20 18:31:43 -0700572 name = line.split()[0]
573 match = MODULE_KEY_PATTERN.search(name)
574 temp[match.group(1)] = line.strip()
Chris Grossfabf50a2019-05-02 12:42:09 -0700575 return temp
576
Daniel Normand5d70ea2019-06-05 15:13:43 -0700577 framework_dict = read_helper(framework_target_files_dir)
578 vendor_dict = read_helper(vendor_target_files_dir)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700579 merged_dict = {}
Chris Grossfabf50a2019-05-02 12:42:09 -0700580
Bill Peckham19c3feb2020-03-20 18:31:43 -0700581 def filter_into_merged_dict(item_dict, partition_set):
582 for key, value in item_dict.items():
583 match = PARTITION_TAG_PATTERN.search(value)
584
585 if match is None:
586 raise ValueError('Entry missing partition tag: %s' % value)
587
588 partition_tag = match.group(1)
589
590 if partition_tag in partition_set:
591 if key in merged_dict:
592 raise ValueError('Duplicate key %s' % key)
593
594 merged_dict[key] = value
595
596 filter_into_merged_dict(framework_dict, framework_partition_set)
597 filter_into_merged_dict(vendor_dict, vendor_partition_set)
Chris Grossfabf50a2019-05-02 12:42:09 -0700598
599 output_file = os.path.join(output_target_files_dir, 'META', file_name)
600
Bill Peckham19c3feb2020-03-20 18:31:43 -0700601 # The following code is similar to write_sorted_data, but different enough
602 # that we couldn't use that function. We need the output to be sorted by the
603 # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
604 # allows the sort to be consistent with the framework/vendor input data and
605 # eases comparison of input data with merged data.
606 with open(output_file, 'w') as output:
607 for key in sorted(merged_dict.keys()):
608 out_str = merged_dict[key] + '\n'
609 output.write(out_str)
Daniel Normana61cde02019-05-03 14:19:13 -0700610
611
Daniel Normand5d70ea2019-06-05 15:13:43 -0700612def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700613 output_target_files_dir):
614 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700615 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
616 'framework_file_contexts.bin')
617 if not os.path.exists(framework_fc_path):
618 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
619 'file_contexts.bin')
620 if not os.path.exists(framework_fc_path):
621 raise ValueError('Missing framework file_contexts.bin.')
622 shutil.copyfile(
623 framework_fc_path,
624 os.path.join(output_target_files_dir, 'META',
625 'framework_file_contexts.bin'))
626
627 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
628 'vendor_file_contexts.bin')
629 if not os.path.exists(vendor_fc_path):
630 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700631 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700632 if not os.path.exists(vendor_fc_path):
633 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700634 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700635 vendor_fc_path,
636 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700637
638
Daniel Normand5d70ea2019-06-05 15:13:43 -0700639def process_special_cases(framework_target_files_temp_dir,
640 vendor_target_files_temp_dir,
641 output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700642 framework_misc_info_keys,
643 framework_partition_set,
644 vendor_partition_set):
Tao Bao2ad4b822019-06-27 16:52:12 -0700645 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800646
647 Certain files in the output target files package require special-case
648 processing. This function performs all that special-case processing.
649
650 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700651 framework_target_files_temp_dir: The name of a directory containing the
652 special items extracted from the framework target files package.
653 vendor_target_files_temp_dir: The name of a directory containing the special
654 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700655 output_target_files_temp_dir: The name of a directory that will be used to
656 create the output target files package after all the special cases are
657 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700658 framework_misc_info_keys: A list of keys to obtain from the framework
659 instance of META/misc_info.txt. The remaining keys from the vendor
660 instance.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700661 framework_partition_set: Partitions that are considered framework
662 partitions. Used to filter apexkeys.txt and apkcerts.txt.
663 vendor_partition_set: Partitions that are considered vendor partitions. Used
664 to filter apexkeys.txt and apkcerts.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800665 """
666
Daniel Normand5d70ea2019-06-05 15:13:43 -0700667 if 'ab_update' in framework_misc_info_keys:
Bill Peckham364c1cc2019-03-29 18:27:23 -0700668 process_ab_partitions_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700669 framework_target_files_temp_dir=framework_target_files_temp_dir,
670 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700671 output_target_files_temp_dir=output_target_files_temp_dir)
672
Daniel Norman72c626f2019-05-13 15:58:14 -0700673 copy_file_contexts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700674 framework_target_files_dir=framework_target_files_temp_dir,
675 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700676 output_target_files_dir=output_target_files_temp_dir)
677
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800678 process_misc_info_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,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800681 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700682 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800683
Daniel Normana61cde02019-05-03 14:19:13 -0700684 process_dynamic_partitions_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700685 framework_target_files_dir=framework_target_files_temp_dir,
686 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman714bd122019-05-08 16:20:02 -0700687 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700688
Chris Grossfabf50a2019-05-02 12:42:09 -0700689 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700690 framework_target_files_dir=framework_target_files_temp_dir,
691 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700692 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700693 framework_partition_set=framework_partition_set,
694 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700695 file_name='apkcerts.txt')
696
697 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='apexkeys.txt')
704
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800705
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900706def files_from_path(target_path, extra_args=None):
Tao Bao2ad4b822019-06-27 16:52:12 -0700707 """Gets files under given path.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800708
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900709 Get (sub)files from given target path and return sorted list.
710
711 Args:
712 target_path: Target path to get subfiles.
713 extra_args: List of extra argument for find command. Optional.
714
715 Returns:
716 Sorted files and directories list.
717 """
718
719 find_command = ['find', target_path] + (extra_args or [])
720 find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700721 return common.RunAndCheckOutput(['sort'],
722 stdin=find_process.stdout,
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900723 verbose=False)
724
725
726def create_merged_package(temp_dir, framework_target_files, framework_item_list,
727 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700728 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700729 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800730
731 Args:
732 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700733 input target files packages, and also a scratch directory that we use for
734 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700735 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700736 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700737 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700738 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700739 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700740 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700741 vendor_target_files: The name of the zip archive containing the vendor
742 partial target files package.
743 vendor_item_list: The list of items to extract from the partial vendor
744 target files package as is, meaning these items will land in the output
745 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700746 target files package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900747 framework_misc_info_keys: The list of keys to obtain from the framework
748 instance of META/misc_info.txt. The remaining keys from the vendor
749 instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700750 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700751 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800752
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900753 Returns:
754 Path to merged package under temp directory.
755 """
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800756
Daniel Normand5d70ea2019-06-05 15:13:43 -0700757 # Create directory names that we'll use when we extract files from framework,
758 # and vendor, and for zipping the final output.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800759
Daniel Normand5d70ea2019-06-05 15:13:43 -0700760 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
761 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800762 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
763
Daniel Normand5d70ea2019-06-05 15:13:43 -0700764 # Extract "as is" items from the input framework partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800765 # We extract them directly into the output temporary directory since the
766 # items do not need special case processing.
767
Bill Peckham889b0c62019-02-21 18:53:37 -0800768 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700769 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800770 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700771 extract_item_list=framework_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800772
Daniel Normand5d70ea2019-06-05 15:13:43 -0700773 # Extract "as is" items from the input vendor partial target files package. We
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800774 # extract them directly into the output temporary directory since the items
775 # do not need special case processing.
776
Bill Peckham889b0c62019-02-21 18:53:37 -0800777 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700778 target_files=vendor_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800779 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700780 extract_item_list=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800781
Daniel Normand5d70ea2019-06-05 15:13:43 -0700782 # Extract "special" items from the input framework partial target files
783 # package. We extract these items to different directory since they require
784 # special processing before they will end up in the output directory.
785
786 extract_items(
787 target_files=framework_target_files,
788 target_files_temp_dir=framework_target_files_temp_dir,
789 extract_item_list=FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST)
790
791 # Extract "special" items from the input vendor partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800792 # We extract these items to different directory since they require special
793 # processing before they will end up in the output directory.
794
Bill Peckham889b0c62019-02-21 18:53:37 -0800795 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700796 target_files=vendor_target_files,
797 target_files_temp_dir=vendor_target_files_temp_dir,
798 extract_item_list=VENDOR_EXTRACT_SPECIAL_ITEM_LIST)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800799
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800800 # Now that the temporary directories contain all the extracted files, perform
801 # special case processing on any items that need it. After this function
802 # completes successfully, all the files we need to create the output target
803 # files package are in place.
804
Bill Peckham889b0c62019-02-21 18:53:37 -0800805 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700806 framework_target_files_temp_dir=framework_target_files_temp_dir,
807 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800808 output_target_files_temp_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700809 framework_misc_info_keys=framework_misc_info_keys,
810 framework_partition_set=item_list_to_partition_set(framework_item_list),
811 vendor_partition_set=item_list_to_partition_set(vendor_item_list))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800812
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900813 return output_target_files_temp_dir
814
815
816def generate_images(target_files_dir, rebuild_recovery):
817 """Generate images from target files.
818
819 This function takes merged output temporary directory and create images
820 from it.
821
822 Args:
823 target_files_dir: Path to merged temp directory.
824 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
825 devices and write it to the system image.
826 """
827
828 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800829
Daniel Normana4911da2019-03-15 14:36:21 -0700830 add_img_args = ['--verbose']
Paul Trautrimbc3600c2019-08-13 18:07:03 +0900831 add_img_args.append('--add_missing')
Bill Peckhame868aec2019-09-17 17:06:47 -0700832 # TODO(b/132730255): Remove this if statement.
Daniel Normana4911da2019-03-15 14:36:21 -0700833 if rebuild_recovery:
834 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900835 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800836
837 add_img_to_target_files.main(add_img_args)
838
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900839
840def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700841 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900842
843 Args:
844 target_dir: Path to the target file package which contains misc_info.txt for
845 detailed information for super image.
846 output_super_empty: If provided, copies a super_empty.img file from the
847 target files package to this path.
848 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700849 # Create super_empty.img using the merged misc_info.txt.
850
Daniel Norman4cc9df62019-07-18 10:11:07 -0700851 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700852
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900853 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
854 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700855
856 if use_dynamic_partitions != 'true' and output_super_empty:
857 raise ValueError(
858 'Building super_empty.img requires use_dynamic_partitions=true.')
859 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700860 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700861 build_super_image_args = [
862 misc_info_txt,
863 super_empty_img,
864 ]
865 build_super_image.main(build_super_image_args)
866
867 # Copy super_empty.img to the user-provided output_super_empty location.
868 if output_super_empty:
869 shutil.copyfile(super_empty_img, output_super_empty)
870
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700871
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900872def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700873 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900874
875 Args:
876 output_file: The name of the zip archive target files package.
877 source_dir: The target directory contains package to be archived.
878 temp_dir: Path to temporary directory for any intermediate files.
879 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800880 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900881 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700882 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800883
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900884 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700885 other_content = files_from_path(
886 source_dir,
887 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800888
Tao Bao2ad4b822019-06-27 16:52:12 -0700889 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800890 f.write(meta_content)
891 f.write(other_content)
892
893 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800894 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800895 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700896 '-o',
897 output_zip,
898 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900899 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700900 '-l',
901 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800902 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900903
904 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800905 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900906 logger.info('finished creating %s', output_file)
907
908 return output_zip
909
910
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900911def merge_target_files(temp_dir, framework_target_files, framework_item_list,
912 framework_misc_info_keys, vendor_target_files,
913 vendor_item_list, output_target_files, output_dir,
914 output_item_list, output_ota, output_img,
915 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700916 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900917
918 This function takes framework and vendor target files packages as input,
919 performs various file extractions, special case processing, and finally
920 creates a merged zip archive as output.
921
922 Args:
923 temp_dir: The name of a directory we use when we extract items from the
924 input target files packages, and also a scratch directory that we use for
925 temporary files.
926 framework_target_files: The name of the zip archive containing the framework
927 partial target files package.
928 framework_item_list: The list of items to extract from the partial framework
929 target files package as is, meaning these items will land in the output
930 target files package exactly as they appear in the input partial framework
931 target files package.
932 framework_misc_info_keys: The list of keys to obtain from the framework
933 instance of META/misc_info.txt. The remaining keys from the vendor
934 instance.
935 vendor_target_files: The name of the zip archive containing the vendor
936 partial target files package.
937 vendor_item_list: The list of items to extract from the partial vendor
938 target files package as is, meaning these items will land in the output
939 target files package exactly as they appear in the input partial vendor
940 target files package.
941 output_target_files: The name of the output zip archive target files package
942 created by merging framework and vendor.
943 output_dir: The destination directory for saving merged files.
944 output_item_list: The list of items to copy into the output_dir.
945 output_ota: The name of the output zip archive ota package.
946 output_img: The name of the output zip archive img package.
947 output_super_empty: If provided, creates a super_empty.img file from the
948 merged target files package and saves it at this path.
949 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
950 devices and write it to the system image.
951 """
952
953 logger.info('starting: merge framework %s and vendor %s into output %s',
954 framework_target_files, vendor_target_files, output_target_files)
955
956 output_target_files_temp_dir = create_merged_package(
957 temp_dir, framework_target_files, framework_item_list,
958 vendor_target_files, vendor_item_list, framework_misc_info_keys,
959 rebuild_recovery)
960
Yifan Hongade0d3f2019-08-21 16:37:11 -0700961 if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
962 raise RuntimeError("Incompatible VINTF metadata")
963
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900964 generate_images(output_target_files_temp_dir, rebuild_recovery)
965
966 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
967
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900968 # Finally, create the output target files zip archive and/or copy the
969 # output items to the output target files directory.
970
971 if output_dir:
972 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
973
974 if not output_target_files:
975 return
976
977 output_zip = create_target_files_archive(output_target_files,
978 output_target_files_temp_dir,
979 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800980
Daniel Norman74eb74b2019-09-18 14:01:48 -0700981 # Create the IMG package from the merged target files package.
982
983 if output_img:
984 img_from_target_files.main([output_zip, output_img])
985
Daniel Norman3b64ce12019-04-16 16:11:35 -0700986 # Create the OTA package from the merged target files package.
987
988 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700989 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -0700990
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700991
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800992def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -0700993 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800994
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800995 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800996 directory. It also cleans up the temporary directory.
997
998 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -0700999 func: The function to call. Should accept one parameter, the path to the
1000 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001001 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001002 """
1003
1004 # Create a temporary directory. This will serve as the parent of directories
1005 # we use when we extract items from the input target files packages, and also
1006 # a scratch directory that we use for temporary files.
1007
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001008 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
1009
1010 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001011 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001012 finally:
1013 if keep_tmp:
1014 logger.info('keeping %s', temp_dir)
1015 else:
1016 common.Cleanup()
1017
1018
1019def main():
1020 """The main function.
1021
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001022 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001023 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001024 """
1025
1026 common.InitLogging()
1027
Bill Peckhamf753e152019-02-19 18:02:46 -08001028 def option_handler(o, a):
1029 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001030 logger.warning(
1031 '--system-target-files has been renamed to --framework-target-files')
1032 OPTIONS.framework_target_files = a
1033 elif o == '--framework-target-files':
1034 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001035 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001036 logger.warning(
1037 '--system-item-list has been renamed to --framework-item-list')
1038 OPTIONS.framework_item_list = a
1039 elif o == '--framework-item-list':
1040 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001041 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001042 logger.warning('--system-misc-info-keys has been renamed to '
1043 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001044 OPTIONS.framework_misc_info_keys = a
1045 elif o == '--framework-misc-info-keys':
1046 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001047 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001048 logger.warning(
1049 '--other-target-files has been renamed to --vendor-target-files')
1050 OPTIONS.vendor_target_files = a
1051 elif o == '--vendor-target-files':
1052 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001053 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001054 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1055 OPTIONS.vendor_item_list = a
1056 elif o == '--vendor-item-list':
1057 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001058 elif o == '--output-target-files':
1059 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001060 elif o == '--output-dir':
1061 OPTIONS.output_dir = a
1062 elif o == '--output-item-list':
1063 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001064 elif o == '--output-ota':
1065 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001066 elif o == '--output-img':
1067 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001068 elif o == '--output-super-empty':
1069 OPTIONS.output_super_empty = a
Bill Peckhame868aec2019-09-17 17:06:47 -07001070 elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
Daniel Normana4911da2019-03-15 14:36:21 -07001071 OPTIONS.rebuild_recovery = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001072 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001073 OPTIONS.keep_tmp = True
1074 else:
1075 return False
1076 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001077
Bill Peckhamf753e152019-02-19 18:02:46 -08001078 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001079 sys.argv[1:],
1080 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001081 extra_long_opts=[
1082 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001083 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001084 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001085 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001086 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001087 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001088 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001089 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001090 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001091 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001092 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001093 'output-dir=',
1094 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001095 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001096 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001097 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001098 'rebuild_recovery',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001099 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001100 ],
1101 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001102
Tao Bao2ad4b822019-06-27 16:52:12 -07001103 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001104 if (args or OPTIONS.framework_target_files is None or
1105 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001106 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1107 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001108 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001109 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001110
Tao Baoabb806b2019-08-06 10:32:32 -07001111 # Always turn on verbose logging.
1112 OPTIONS.verbose = True
1113
Daniel Normand5d70ea2019-06-05 15:13:43 -07001114 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001115 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001116 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001117 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001118
Daniel Normand5d70ea2019-06-05 15:13:43 -07001119 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001120 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001121 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001122 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001123 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001124
Daniel Normand5d70ea2019-06-05 15:13:43 -07001125 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001126 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001127 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001128 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001129
Daniel Normanfdb38812019-04-15 09:47:24 -07001130 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001131 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001132 else:
1133 output_item_list = None
1134
Daniel Normane5964522019-03-19 10:32:03 -07001135 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001136 framework_item_list=framework_item_list,
1137 framework_misc_info_keys=framework_misc_info_keys,
1138 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001139 sys.exit(1)
1140
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001141 call_func_with_temp_dir(
1142 lambda temp_dir: merge_target_files(
1143 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001144 framework_target_files=OPTIONS.framework_target_files,
1145 framework_item_list=framework_item_list,
1146 framework_misc_info_keys=framework_misc_info_keys,
1147 vendor_target_files=OPTIONS.vendor_target_files,
1148 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001149 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001150 output_dir=OPTIONS.output_dir,
1151 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001152 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001153 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001154 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001155 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001156
1157
1158if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001159 main()