blob: dd7806bde0200772bf53b23e498d08793a4738ee [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
Bill Peckham5c7b0342020-04-03 15:36:23 -0700120# In apexkeys.txt or apkcerts.txt, we will find partition tags on each entry in
121# the file. We use these partition tags to filter the entries in those files
122# from the two different target files packages to produce a merged apexkeys.txt
123# or apkcerts.txt file. A partition tag (e.g., for the product partition) looks
124# like this: 'partition="product"'. We use the group syntax grab the value of
125# the tag. We use non-greedy matching in case there are other fields on the
126# same line.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700127
Bill Peckham5c7b0342020-04-03 15:36:23 -0700128PARTITION_TAG_PATTERN = re.compile(r'partition="(.*?)"')
Bill Peckham19c3feb2020-03-20 18:31:43 -0700129
130# The sorting algorithm for apexkeys.txt and apkcerts.txt does not include the
131# ".apex" or ".apk" suffix, so we use the following pattern to extract a key.
132
133MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
134
Daniel Normand5d70ea2019-06-05 15:13:43 -0700135# DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
136# framework target files package as is, meaning these items will land in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800137# output target files package exactly as they appear in the input partial
Daniel Normand5d70ea2019-06-05 15:13:43 -0700138# framework target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800139
Daniel Normand5d70ea2019-06-05 15:13:43 -0700140DEFAULT_FRAMEWORK_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800141 'META/apkcerts.txt',
142 'META/filesystem_config.txt',
143 'META/root_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800144 'META/update_engine_config.txt',
145 'PRODUCT/*',
146 'ROOT/*',
147 'SYSTEM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700148)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800149
Daniel Normand5d70ea2019-06-05 15:13:43 -0700150# FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
151# partial framework target files package that need some special processing, such
152# as some sort of combination with items from the partial vendor target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800153# package.
154
Daniel Normand5d70ea2019-06-05 15:13:43 -0700155FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800156
Daniel Normand5d70ea2019-06-05 15:13:43 -0700157# DEFAULT_FRAMEWORK_MISC_INFO_KEYS is a list of keys to obtain from the
158# framework instance of META/misc_info.txt. The remaining keys from the
159# vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800160
Daniel Normand5d70ea2019-06-05 15:13:43 -0700161DEFAULT_FRAMEWORK_MISC_INFO_KEYS = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800162 'avb_system_hashtree_enable',
163 'avb_system_add_hashtree_footer_args',
164 'avb_system_key_path',
165 'avb_system_algorithm',
166 'avb_system_rollback_index_location',
167 'avb_product_hashtree_enable',
168 'avb_product_add_hashtree_footer_args',
Justin Yun6151e3f2019-06-25 15:58:13 +0900169 'avb_system_ext_hashtree_enable',
170 'avb_system_ext_add_hashtree_footer_args',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800171 'system_root_image',
172 'root_dir',
173 'ab_update',
174 'default_system_dev_certificate',
175 'system_size',
Daniel Normanedf12472019-05-22 10:47:08 -0700176)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800177
Daniel Normand5d70ea2019-06-05 15:13:43 -0700178# DEFAULT_VENDOR_ITEM_LIST is a list of items to extract from the partial
179# vendor target files package as is, meaning these items will land in the output
180# target files package exactly as they appear in the input partial vendor target
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800181# files package.
182
Daniel Normand5d70ea2019-06-05 15:13:43 -0700183DEFAULT_VENDOR_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800184 'META/boot_filesystem_config.txt',
185 'META/otakeys.txt',
186 'META/releasetools.py',
187 'META/vendor_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800188 'BOOT/*',
189 'DATA/*',
190 'ODM/*',
191 'OTA/android-info.txt',
192 'PREBUILT_IMAGES/*',
193 'RADIO/*',
194 'VENDOR/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700195)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800196
Daniel Normand5d70ea2019-06-05 15:13:43 -0700197# VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
198# partial vendor target files package that need some special processing, such as
199# some sort of combination with items from the partial framework target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800200# package.
201
Daniel Normand5d70ea2019-06-05 15:13:43 -0700202VENDOR_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Daniel Normanedf12472019-05-22 10:47:08 -0700203
204# The merge config lists should not attempt to extract items from both
205# builds for any of the following partitions. The partitions in
206# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700207# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700208
209SINGLE_BUILD_PARTITIONS = (
210 'BOOT/',
211 'DATA/',
212 'ODM/',
213 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900214 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700215 'RADIO/',
216 'RECOVERY/',
217 'ROOT/',
218 'SYSTEM/',
219 'SYSTEM_OTHER/',
220 'VENDOR/',
221)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800222
223
Chris Grossfabf50a2019-05-02 12:42:09 -0700224def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700225 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700226
Tao Bao2ad4b822019-06-27 16:52:12 -0700227 This function sorts the contents of the list or dict and then writes the
228 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700229
230 Args:
231 data: The list or dict to sort and write.
232 path: Path to the file to write the sorted values to. The file at path will
233 be overridden if it exists.
234 """
235 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700236 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700237 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
238 data, dict) else '{}\n'.format(entry)
239 output.write(out_str)
240
241
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800242def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700243 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800244
245 This function extracts from the specified target files zip archive into the
246 specified temporary directory, the items specified in the extract item list.
247
248 Args:
249 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800250 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700251 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800252 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800253 """
254
255 logger.info('extracting from %s', target_files)
256
257 # Filter the extract_item_list to remove any items that do not exist in the
258 # zip file. Otherwise, the extraction step will fail.
259
Daniel Norman4cc9df62019-07-18 10:11:07 -0700260 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800261 target_files_namelist = target_files_zipfile.namelist()
262
263 filtered_extract_item_list = []
264 for pattern in extract_item_list:
265 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
266 if not matching_namelist:
267 logger.warning('no match for %s', pattern)
268 else:
269 filtered_extract_item_list.append(pattern)
270
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800271 # Extract from target_files into target_files_temp_dir the
272 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800273
Daniel Normane5b134a2019-04-17 14:54:06 -0700274 common.UnzipToDir(target_files, target_files_temp_dir,
275 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800276
277
Daniel Normanfdb38812019-04-15 09:47:24 -0700278def copy_items(from_dir, to_dir, patterns):
279 """Similar to extract_items() except uses an input dir instead of zip."""
280 file_paths = []
281 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700282 file_paths.extend(
283 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
284 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700285
286 filtered_file_paths = set()
287 for pattern in patterns:
288 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
289
290 for file_path in filtered_file_paths:
291 original_file_path = os.path.join(from_dir, file_path)
292 copied_file_path = os.path.join(to_dir, file_path)
293 copied_file_dir = os.path.dirname(copied_file_path)
294 if not os.path.exists(copied_file_dir):
295 os.makedirs(copied_file_dir)
296 if os.path.islink(original_file_path):
297 os.symlink(os.readlink(original_file_path), copied_file_path)
298 else:
299 shutil.copyfile(original_file_path, copied_file_path)
300
301
Daniel Normand5d70ea2019-06-05 15:13:43 -0700302def validate_config_lists(framework_item_list, framework_misc_info_keys,
303 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700304 """Performs validations on the merge config lists.
305
306 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700307 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700308 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700309 framework_misc_info_keys: A list of keys to obtain from the framework
310 instance of META/misc_info.txt. The remaining keys from the vendor
311 instance.
312 vendor_item_list: The list of items to extract from the partial vendor
313 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700314
315 Returns:
316 False if a validation fails, otherwise true.
317 """
Daniel Normanedf12472019-05-22 10:47:08 -0700318 has_error = False
319
Daniel Normand5d70ea2019-06-05 15:13:43 -0700320 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
321 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700322
Daniel Normand5d70ea2019-06-05 15:13:43 -0700323 combined_item_set = set(framework_item_list)
324 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700325
326 # Check that the merge config lists are not missing any item specified
327 # by the default config lists.
328 difference = default_combined_item_set.difference(combined_item_set)
329 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700330 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700331 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700332 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700333 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700334 has_error = True
335
336 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700337 in_framework = any(
338 item.startswith(partition) for item in framework_item_list)
339 in_vendor = any(item.startswith(partition) for item in vendor_item_list)
340 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700341 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700342 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900343 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700344 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700345 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700346
Daniel Normand5d70ea2019-06-05 15:13:43 -0700347 if ('dynamic_partition_list' in framework_misc_info_keys) or (
348 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700349 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700350 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700351 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700352
Daniel Normanedf12472019-05-22 10:47:08 -0700353 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700354
355
Daniel Normand5d70ea2019-06-05 15:13:43 -0700356def process_ab_partitions_txt(framework_target_files_temp_dir,
357 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700358 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700359 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800360
Tao Bao2ad4b822019-06-27 16:52:12 -0700361 This function merges the contents of the META/ab_partitions.txt files from the
362 framework directory and the vendor directory, placing the merged result in the
363 output directory. The precondition in that the files are already extracted.
364 The post condition is that the output META/ab_partitions.txt contains the
365 merged content. The format for each ab_partitions.txt a one partition name per
366 line. The output file contains the union of the parition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800367
368 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700369 framework_target_files_temp_dir: The name of a directory containing the
370 special items extracted from the framework target files package.
371 vendor_target_files_temp_dir: The name of a directory containing the special
372 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700373 output_target_files_temp_dir: The name of a directory that will be used to
374 create the output target files package after all the special cases are
375 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800376 """
377
Daniel Normand5d70ea2019-06-05 15:13:43 -0700378 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
379 'META', 'ab_partitions.txt')
380
381 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700382 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800383
Daniel Normand5d70ea2019-06-05 15:13:43 -0700384 with open(framework_ab_partitions_txt) as f:
385 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800386
Daniel Normand5d70ea2019-06-05 15:13:43 -0700387 with open(vendor_ab_partitions_txt) as f:
388 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800389
Daniel Normand5d70ea2019-06-05 15:13:43 -0700390 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800391
Daniel Normane5b134a2019-04-17 14:54:06 -0700392 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
393 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800394
Chris Grossfabf50a2019-05-02 12:42:09 -0700395 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800396
397
Daniel Normand5d70ea2019-06-05 15:13:43 -0700398def process_misc_info_txt(framework_target_files_temp_dir,
399 vendor_target_files_temp_dir,
400 output_target_files_temp_dir,
401 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700402 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800403
404 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700405 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800406 output directory. The precondition in that the files are already extracted.
407 The post condition is that the output META/misc_info.txt contains the merged
408 content.
409
410 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700411 framework_target_files_temp_dir: The name of a directory containing the
412 special items extracted from the framework target files package.
413 vendor_target_files_temp_dir: The name of a directory containing the special
414 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700415 output_target_files_temp_dir: The name of a directory that will be used to
416 create the output target files package after all the special cases are
417 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700418 framework_misc_info_keys: A list of keys to obtain from the framework
419 instance of META/misc_info.txt. The remaining keys from the vendor
420 instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800421 """
422
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900423 misc_info_path = ['META', 'misc_info.txt']
424 framework_dict = common.LoadDictionaryFromFile(
425 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800426
Daniel Normand5d70ea2019-06-05 15:13:43 -0700427 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800428
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900429 merged_dict = common.LoadDictionaryFromFile(
430 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800431
Daniel Normand5d70ea2019-06-05 15:13:43 -0700432 # Replace certain values in merged_dict with values from
433 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800434
Daniel Normand5d70ea2019-06-05 15:13:43 -0700435 for key in framework_misc_info_keys:
436 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800437
Daniel Norman19b9fe92019-03-19 14:48:02 -0700438 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700439 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
440 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700441 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Norman55417142019-11-25 16:04:36 -0800442 framework_dict=framework_dict, vendor_dict=merged_dict)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700443 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700444 # Ensure that add_img_to_target_files rebuilds super split images for
445 # devices that retrofit dynamic partitions. This flag may have been set to
446 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700447 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700448
Daniel Normand5d70ea2019-06-05 15:13:43 -0700449 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700450 # depending on which dictionary the key came from.
451 # Only the file basename is required because all selinux_fc properties are
452 # replaced with the full path to the file under META/ when misc_info.txt is
453 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700454 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700455 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700456 merged_dict[key] = 'vendor_file_contexts.bin'
457 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700458 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700459 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700460
Daniel Normane5b134a2019-04-17 14:54:06 -0700461 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
462 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700463 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800464
465
Daniel Normand5d70ea2019-06-05 15:13:43 -0700466def process_dynamic_partitions_info_txt(framework_target_files_dir,
467 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700468 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700469 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700470
471 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700472 files from the framework directory and the vendor directory, placing the
473 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700474
Daniel Normand5d70ea2019-06-05 15:13:43 -0700475 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700476 directory does not exist.
477
478 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700479 framework_target_files_dir: The name of a directory containing the special
480 items extracted from the framework target files package.
481 vendor_target_files_dir: The name of a directory containing the special
482 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700483 output_target_files_dir: The name of a directory that will be used to create
484 the output target files package after all the special cases are processed.
485 """
486
487 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700488 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700489 'dynamic_partitions_info.txt')):
490 return
491
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900492 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700493
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900494 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
495 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
496 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
497 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700498
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700499 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700500 framework_dict=framework_dynamic_partitions_dict,
Daniel Norman55417142019-11-25 16:04:36 -0800501 vendor_dict=vendor_dynamic_partitions_dict)
Daniel Normana61cde02019-05-03 14:19:13 -0700502
503 output_dynamic_partitions_info_txt = os.path.join(
504 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700505 write_sorted_data(
506 data=merged_dynamic_partitions_dict,
507 path=output_dynamic_partitions_info_txt)
508
509
Bill Peckham19c3feb2020-03-20 18:31:43 -0700510def item_list_to_partition_set(item_list):
511 """Converts a target files item list to a partition set.
512
513 The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
514 'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
515 directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
516 contents of a partition of the same name. Other items in the list, such as the
517 'OTA' example contain metadata. This function iterates such a list, returning
518 a set that contains the partition entries.
519
520 Args:
521 item_list: A list of items in a target files package.
522 Returns:
523 A set of partitions extracted from the list of items.
524 """
525
526 partition_set = set()
527
528 for item in item_list:
529 match = PARTITION_ITEM_PATTERN.search(item.strip())
530 partition_tag = match.group(1).lower() if match else None
531
532 if partition_tag:
533 partition_set.add(partition_tag)
534
535 return partition_set
536
537
Daniel Normand5d70ea2019-06-05 15:13:43 -0700538def process_apex_keys_apk_certs_common(framework_target_files_dir,
539 vendor_target_files_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700540 output_target_files_dir,
541 framework_partition_set,
542 vendor_partition_set, file_name):
543
Tao Bao2ad4b822019-06-27 16:52:12 -0700544 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700545
546 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700547 META/apkcerts.txt files from the framework directory and the vendor directory,
548 placing the merged result in the output directory. The precondition in that
549 the files are already extracted. The post condition is that the output
550 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700551
552 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700553 framework_target_files_dir: The name of a directory containing the special
554 items extracted from the framework target files package.
555 vendor_target_files_dir: The name of a directory containing the special
556 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700557 output_target_files_dir: The name of a directory that will be used to create
558 the output target files package after all the special cases are processed.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700559 framework_partition_set: Partitions that are considered framework
560 partitions. Used to filter apexkeys.txt and apkcerts.txt.
561 vendor_partition_set: Partitions that are considered vendor partitions. Used
562 to filter apexkeys.txt and apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700563 file_name: The name of the file to merge. One of apkcerts.txt or
564 apexkeys.txt.
565 """
566
567 def read_helper(d):
568 temp = {}
569 file_path = os.path.join(d, 'META', file_name)
570 with open(file_path) as f:
571 for line in f:
572 if line.strip():
Bill Peckham19c3feb2020-03-20 18:31:43 -0700573 name = line.split()[0]
574 match = MODULE_KEY_PATTERN.search(name)
575 temp[match.group(1)] = line.strip()
Chris Grossfabf50a2019-05-02 12:42:09 -0700576 return temp
577
Daniel Normand5d70ea2019-06-05 15:13:43 -0700578 framework_dict = read_helper(framework_target_files_dir)
579 vendor_dict = read_helper(vendor_target_files_dir)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700580 merged_dict = {}
Chris Grossfabf50a2019-05-02 12:42:09 -0700581
Bill Peckham19c3feb2020-03-20 18:31:43 -0700582 def filter_into_merged_dict(item_dict, partition_set):
583 for key, value in item_dict.items():
584 match = PARTITION_TAG_PATTERN.search(value)
585
586 if match is None:
587 raise ValueError('Entry missing partition tag: %s' % value)
588
589 partition_tag = match.group(1)
590
591 if partition_tag in partition_set:
592 if key in merged_dict:
593 raise ValueError('Duplicate key %s' % key)
594
595 merged_dict[key] = value
596
597 filter_into_merged_dict(framework_dict, framework_partition_set)
598 filter_into_merged_dict(vendor_dict, vendor_partition_set)
Chris Grossfabf50a2019-05-02 12:42:09 -0700599
600 output_file = os.path.join(output_target_files_dir, 'META', file_name)
601
Bill Peckham19c3feb2020-03-20 18:31:43 -0700602 # The following code is similar to write_sorted_data, but different enough
603 # that we couldn't use that function. We need the output to be sorted by the
604 # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
605 # allows the sort to be consistent with the framework/vendor input data and
606 # eases comparison of input data with merged data.
607 with open(output_file, 'w') as output:
608 for key in sorted(merged_dict.keys()):
609 out_str = merged_dict[key] + '\n'
610 output.write(out_str)
Daniel Normana61cde02019-05-03 14:19:13 -0700611
612
Daniel Normand5d70ea2019-06-05 15:13:43 -0700613def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700614 output_target_files_dir):
615 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700616 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
617 'framework_file_contexts.bin')
618 if not os.path.exists(framework_fc_path):
619 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
620 'file_contexts.bin')
621 if not os.path.exists(framework_fc_path):
622 raise ValueError('Missing framework file_contexts.bin.')
623 shutil.copyfile(
624 framework_fc_path,
625 os.path.join(output_target_files_dir, 'META',
626 'framework_file_contexts.bin'))
627
628 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
629 'vendor_file_contexts.bin')
630 if not os.path.exists(vendor_fc_path):
631 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700632 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700633 if not os.path.exists(vendor_fc_path):
634 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700635 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700636 vendor_fc_path,
637 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700638
639
Daniel Normand5d70ea2019-06-05 15:13:43 -0700640def process_special_cases(framework_target_files_temp_dir,
641 vendor_target_files_temp_dir,
642 output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700643 framework_misc_info_keys,
644 framework_partition_set,
645 vendor_partition_set):
Tao Bao2ad4b822019-06-27 16:52:12 -0700646 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800647
648 Certain files in the output target files package require special-case
649 processing. This function performs all that special-case processing.
650
651 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700652 framework_target_files_temp_dir: The name of a directory containing the
653 special items extracted from the framework target files package.
654 vendor_target_files_temp_dir: The name of a directory containing the special
655 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700656 output_target_files_temp_dir: The name of a directory that will be used to
657 create the output target files package after all the special cases are
658 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700659 framework_misc_info_keys: A list of keys to obtain from the framework
660 instance of META/misc_info.txt. The remaining keys from the vendor
661 instance.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700662 framework_partition_set: Partitions that are considered framework
663 partitions. Used to filter apexkeys.txt and apkcerts.txt.
664 vendor_partition_set: Partitions that are considered vendor partitions. Used
665 to filter apexkeys.txt and apkcerts.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800666 """
667
Daniel Normand5d70ea2019-06-05 15:13:43 -0700668 if 'ab_update' in framework_misc_info_keys:
Bill Peckham364c1cc2019-03-29 18:27:23 -0700669 process_ab_partitions_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700670 framework_target_files_temp_dir=framework_target_files_temp_dir,
671 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700672 output_target_files_temp_dir=output_target_files_temp_dir)
673
Daniel Norman72c626f2019-05-13 15:58:14 -0700674 copy_file_contexts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700675 framework_target_files_dir=framework_target_files_temp_dir,
676 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700677 output_target_files_dir=output_target_files_temp_dir)
678
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800679 process_misc_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700680 framework_target_files_temp_dir=framework_target_files_temp_dir,
681 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800682 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700683 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800684
Daniel Normana61cde02019-05-03 14:19:13 -0700685 process_dynamic_partitions_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700686 framework_target_files_dir=framework_target_files_temp_dir,
687 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman714bd122019-05-08 16:20:02 -0700688 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700689
Chris Grossfabf50a2019-05-02 12:42:09 -0700690 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700691 framework_target_files_dir=framework_target_files_temp_dir,
692 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700693 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700694 framework_partition_set=framework_partition_set,
695 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700696 file_name='apkcerts.txt')
697
698 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700699 framework_target_files_dir=framework_target_files_temp_dir,
700 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700701 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700702 framework_partition_set=framework_partition_set,
703 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700704 file_name='apexkeys.txt')
705
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800706
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900707def files_from_path(target_path, extra_args=None):
Tao Bao2ad4b822019-06-27 16:52:12 -0700708 """Gets files under given path.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800709
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900710 Get (sub)files from given target path and return sorted list.
711
712 Args:
713 target_path: Target path to get subfiles.
714 extra_args: List of extra argument for find command. Optional.
715
716 Returns:
717 Sorted files and directories list.
718 """
719
720 find_command = ['find', target_path] + (extra_args or [])
721 find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700722 return common.RunAndCheckOutput(['sort'],
723 stdin=find_process.stdout,
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900724 verbose=False)
725
726
727def create_merged_package(temp_dir, framework_target_files, framework_item_list,
728 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700729 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700730 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800731
732 Args:
733 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700734 input target files packages, and also a scratch directory that we use for
735 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700736 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700737 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700738 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700739 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700740 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700741 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700742 vendor_target_files: The name of the zip archive containing the vendor
743 partial target files package.
744 vendor_item_list: The list of items to extract from the partial vendor
745 target files package as is, meaning these items will land in the output
746 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700747 target files package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900748 framework_misc_info_keys: The list of keys to obtain from the framework
749 instance of META/misc_info.txt. The remaining keys from the vendor
750 instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700751 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700752 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800753
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900754 Returns:
755 Path to merged package under temp directory.
756 """
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800757
Daniel Normand5d70ea2019-06-05 15:13:43 -0700758 # Create directory names that we'll use when we extract files from framework,
759 # and vendor, and for zipping the final output.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800760
Daniel Normand5d70ea2019-06-05 15:13:43 -0700761 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
762 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800763 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
764
Daniel Normand5d70ea2019-06-05 15:13:43 -0700765 # Extract "as is" items from the input framework partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800766 # We extract them directly into the output temporary directory since the
767 # items do not need special case processing.
768
Bill Peckham889b0c62019-02-21 18:53:37 -0800769 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700770 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800771 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700772 extract_item_list=framework_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800773
Daniel Normand5d70ea2019-06-05 15:13:43 -0700774 # Extract "as is" items from the input vendor partial target files package. We
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800775 # extract them directly into the output temporary directory since the items
776 # 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=vendor_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=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800782
Daniel Normand5d70ea2019-06-05 15:13:43 -0700783 # Extract "special" items from the input framework partial target files
784 # package. We extract these items to different directory since they require
785 # special processing before they will end up in the output directory.
786
787 extract_items(
788 target_files=framework_target_files,
789 target_files_temp_dir=framework_target_files_temp_dir,
790 extract_item_list=FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST)
791
792 # Extract "special" items from the input vendor partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800793 # We extract these items to different directory since they require special
794 # processing before they will end up in the output directory.
795
Bill Peckham889b0c62019-02-21 18:53:37 -0800796 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700797 target_files=vendor_target_files,
798 target_files_temp_dir=vendor_target_files_temp_dir,
799 extract_item_list=VENDOR_EXTRACT_SPECIAL_ITEM_LIST)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800800
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800801 # Now that the temporary directories contain all the extracted files, perform
802 # special case processing on any items that need it. After this function
803 # completes successfully, all the files we need to create the output target
804 # files package are in place.
805
Bill Peckham889b0c62019-02-21 18:53:37 -0800806 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700807 framework_target_files_temp_dir=framework_target_files_temp_dir,
808 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800809 output_target_files_temp_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700810 framework_misc_info_keys=framework_misc_info_keys,
811 framework_partition_set=item_list_to_partition_set(framework_item_list),
812 vendor_partition_set=item_list_to_partition_set(vendor_item_list))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800813
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900814 return output_target_files_temp_dir
815
816
817def generate_images(target_files_dir, rebuild_recovery):
818 """Generate images from target files.
819
820 This function takes merged output temporary directory and create images
821 from it.
822
823 Args:
824 target_files_dir: Path to merged temp directory.
825 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
826 devices and write it to the system image.
827 """
828
829 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800830
Daniel Normana4911da2019-03-15 14:36:21 -0700831 add_img_args = ['--verbose']
Paul Trautrimbc3600c2019-08-13 18:07:03 +0900832 add_img_args.append('--add_missing')
Bill Peckhame868aec2019-09-17 17:06:47 -0700833 # TODO(b/132730255): Remove this if statement.
Daniel Normana4911da2019-03-15 14:36:21 -0700834 if rebuild_recovery:
835 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900836 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800837
838 add_img_to_target_files.main(add_img_args)
839
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900840
841def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700842 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900843
844 Args:
845 target_dir: Path to the target file package which contains misc_info.txt for
846 detailed information for super image.
847 output_super_empty: If provided, copies a super_empty.img file from the
848 target files package to this path.
849 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700850 # Create super_empty.img using the merged misc_info.txt.
851
Daniel Norman4cc9df62019-07-18 10:11:07 -0700852 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700853
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900854 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
855 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700856
857 if use_dynamic_partitions != 'true' and output_super_empty:
858 raise ValueError(
859 'Building super_empty.img requires use_dynamic_partitions=true.')
860 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700861 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700862 build_super_image_args = [
863 misc_info_txt,
864 super_empty_img,
865 ]
866 build_super_image.main(build_super_image_args)
867
868 # Copy super_empty.img to the user-provided output_super_empty location.
869 if output_super_empty:
870 shutil.copyfile(super_empty_img, output_super_empty)
871
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700872
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900873def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700874 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900875
876 Args:
877 output_file: The name of the zip archive target files package.
878 source_dir: The target directory contains package to be archived.
879 temp_dir: Path to temporary directory for any intermediate files.
880 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800881 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900882 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700883 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800884
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900885 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700886 other_content = files_from_path(
887 source_dir,
888 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800889
Tao Bao2ad4b822019-06-27 16:52:12 -0700890 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800891 f.write(meta_content)
892 f.write(other_content)
893
894 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800895 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800896 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700897 '-o',
898 output_zip,
899 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900900 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700901 '-l',
902 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800903 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900904
905 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800906 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900907 logger.info('finished creating %s', output_file)
908
909 return output_zip
910
911
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900912def merge_target_files(temp_dir, framework_target_files, framework_item_list,
913 framework_misc_info_keys, vendor_target_files,
914 vendor_item_list, output_target_files, output_dir,
915 output_item_list, output_ota, output_img,
916 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700917 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900918
919 This function takes framework and vendor target files packages as input,
920 performs various file extractions, special case processing, and finally
921 creates a merged zip archive as output.
922
923 Args:
924 temp_dir: The name of a directory we use when we extract items from the
925 input target files packages, and also a scratch directory that we use for
926 temporary files.
927 framework_target_files: The name of the zip archive containing the framework
928 partial target files package.
929 framework_item_list: The list of items to extract from the partial framework
930 target files package as is, meaning these items will land in the output
931 target files package exactly as they appear in the input partial framework
932 target files package.
933 framework_misc_info_keys: The list of keys to obtain from the framework
934 instance of META/misc_info.txt. The remaining keys from the vendor
935 instance.
936 vendor_target_files: The name of the zip archive containing the vendor
937 partial target files package.
938 vendor_item_list: The list of items to extract from the partial vendor
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 vendor
941 target files package.
942 output_target_files: The name of the output zip archive target files package
943 created by merging framework and vendor.
944 output_dir: The destination directory for saving merged files.
945 output_item_list: The list of items to copy into the output_dir.
946 output_ota: The name of the output zip archive ota package.
947 output_img: The name of the output zip archive img package.
948 output_super_empty: If provided, creates a super_empty.img file from the
949 merged target files package and saves it at this path.
950 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
951 devices and write it to the system image.
952 """
953
954 logger.info('starting: merge framework %s and vendor %s into output %s',
955 framework_target_files, vendor_target_files, output_target_files)
956
957 output_target_files_temp_dir = create_merged_package(
958 temp_dir, framework_target_files, framework_item_list,
959 vendor_target_files, vendor_item_list, framework_misc_info_keys,
960 rebuild_recovery)
961
Yifan Hongade0d3f2019-08-21 16:37:11 -0700962 if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
963 raise RuntimeError("Incompatible VINTF metadata")
964
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900965 generate_images(output_target_files_temp_dir, rebuild_recovery)
966
967 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
968
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900969 # Finally, create the output target files zip archive and/or copy the
970 # output items to the output target files directory.
971
972 if output_dir:
973 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
974
975 if not output_target_files:
976 return
977
978 output_zip = create_target_files_archive(output_target_files,
979 output_target_files_temp_dir,
980 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800981
Daniel Norman74eb74b2019-09-18 14:01:48 -0700982 # Create the IMG package from the merged target files package.
983
984 if output_img:
985 img_from_target_files.main([output_zip, output_img])
986
Daniel Norman3b64ce12019-04-16 16:11:35 -0700987 # Create the OTA package from the merged target files package.
988
989 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700990 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -0700991
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700992
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800993def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -0700994 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800995
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800996 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800997 directory. It also cleans up the temporary directory.
998
999 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -07001000 func: The function to call. Should accept one parameter, the path to the
1001 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001002 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001003 """
1004
1005 # Create a temporary directory. This will serve as the parent of directories
1006 # we use when we extract items from the input target files packages, and also
1007 # a scratch directory that we use for temporary files.
1008
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001009 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
1010
1011 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001012 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001013 finally:
1014 if keep_tmp:
1015 logger.info('keeping %s', temp_dir)
1016 else:
1017 common.Cleanup()
1018
1019
1020def main():
1021 """The main function.
1022
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001023 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001024 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001025 """
1026
1027 common.InitLogging()
1028
Bill Peckhamf753e152019-02-19 18:02:46 -08001029 def option_handler(o, a):
1030 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001031 logger.warning(
1032 '--system-target-files has been renamed to --framework-target-files')
1033 OPTIONS.framework_target_files = a
1034 elif o == '--framework-target-files':
1035 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001036 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001037 logger.warning(
1038 '--system-item-list has been renamed to --framework-item-list')
1039 OPTIONS.framework_item_list = a
1040 elif o == '--framework-item-list':
1041 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001042 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001043 logger.warning('--system-misc-info-keys has been renamed to '
1044 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001045 OPTIONS.framework_misc_info_keys = a
1046 elif o == '--framework-misc-info-keys':
1047 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001048 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001049 logger.warning(
1050 '--other-target-files has been renamed to --vendor-target-files')
1051 OPTIONS.vendor_target_files = a
1052 elif o == '--vendor-target-files':
1053 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001054 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001055 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1056 OPTIONS.vendor_item_list = a
1057 elif o == '--vendor-item-list':
1058 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001059 elif o == '--output-target-files':
1060 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001061 elif o == '--output-dir':
1062 OPTIONS.output_dir = a
1063 elif o == '--output-item-list':
1064 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001065 elif o == '--output-ota':
1066 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001067 elif o == '--output-img':
1068 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001069 elif o == '--output-super-empty':
1070 OPTIONS.output_super_empty = a
Bill Peckhame868aec2019-09-17 17:06:47 -07001071 elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
Daniel Normana4911da2019-03-15 14:36:21 -07001072 OPTIONS.rebuild_recovery = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001073 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001074 OPTIONS.keep_tmp = True
1075 else:
1076 return False
1077 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001078
Bill Peckhamf753e152019-02-19 18:02:46 -08001079 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001080 sys.argv[1:],
1081 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001082 extra_long_opts=[
1083 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001084 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001085 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001086 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001087 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001088 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001089 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001090 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001091 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001092 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001093 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001094 'output-dir=',
1095 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001096 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001097 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001098 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001099 'rebuild_recovery',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001100 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001101 ],
1102 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001103
Tao Bao2ad4b822019-06-27 16:52:12 -07001104 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001105 if (args or OPTIONS.framework_target_files is None or
1106 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001107 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1108 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001109 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001110 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001111
Tao Baoabb806b2019-08-06 10:32:32 -07001112 # Always turn on verbose logging.
1113 OPTIONS.verbose = True
1114
Daniel Normand5d70ea2019-06-05 15:13:43 -07001115 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001116 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001117 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001118 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001119
Daniel Normand5d70ea2019-06-05 15:13:43 -07001120 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001121 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001122 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001123 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001124 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001125
Daniel Normand5d70ea2019-06-05 15:13:43 -07001126 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001127 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001128 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001129 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001130
Daniel Normanfdb38812019-04-15 09:47:24 -07001131 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001132 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001133 else:
1134 output_item_list = None
1135
Daniel Normane5964522019-03-19 10:32:03 -07001136 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001137 framework_item_list=framework_item_list,
1138 framework_misc_info_keys=framework_misc_info_keys,
1139 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001140 sys.exit(1)
1141
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001142 call_func_with_temp_dir(
1143 lambda temp_dir: merge_target_files(
1144 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001145 framework_target_files=OPTIONS.framework_target_files,
1146 framework_item_list=framework_item_list,
1147 framework_misc_info_keys=framework_misc_info_keys,
1148 vendor_target_files=OPTIONS.vendor_target_files,
1149 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001150 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001151 output_dir=OPTIONS.output_dir,
1152 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001153 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001154 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001155 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001156 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001157
1158
1159if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001160 main()