blob: 2da5cc08d4347cbb21ef6c8fd9ad1db414b7661f [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 Normandbbf5a32020-10-22 16:03:32 -070019One input package contains framework files, and the other contains vendor files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080020
Daniel Normandbbf5a32020-10-22 16:03:32 -070021This script produces a complete, merged target files package:
22 - This package can be used to generate a flashable IMG package.
23 See --output-img.
24 - This package can be used to generate an OTA package. See --output-ota.
25 - The merged package is checked for compatibility between the two inputs.
26
27Usage: merge_target_files [args]
Bill Peckhame9eb5f92019-02-01 15:52:10 -080028
Daniel Normand5d70ea2019-06-05 15:13:43 -070029 --framework-target-files framework-target-files-zip-archive
30 The input target files package containing framework bits. This is a zip
Bill Peckhame9eb5f92019-02-01 15:52:10 -080031 archive.
32
Daniel Normand5d70ea2019-06-05 15:13:43 -070033 --framework-item-list framework-item-list-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_ITEM_LIST if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080036
Daniel Normand5d70ea2019-06-05 15:13:43 -070037 --framework-misc-info-keys framework-misc-info-keys-file
Daniel Norman2c99c5b2019-03-07 13:01:48 -080038 The optional path to a newline-separated config file that replaces the
Daniel Normand5d70ea2019-06-05 15:13:43 -070039 contents of DEFAULT_FRAMEWORK_MISC_INFO_KEYS if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080040
Daniel Normand5d70ea2019-06-05 15:13:43 -070041 --vendor-target-files vendor-target-files-zip-archive
42 The input target files package containing vendor bits. This is a zip
Bill Peckhame9eb5f92019-02-01 15:52:10 -080043 archive.
44
Daniel Normand5d70ea2019-06-05 15:13:43 -070045 --vendor-item-list vendor-item-list-file
Daniel Norman2c99c5b2019-03-07 13:01:48 -080046 The optional path to a newline-separated config file that replaces the
Daniel Normand5d70ea2019-06-05 15:13:43 -070047 contents of DEFAULT_VENDOR_ITEM_LIST if provided.
Daniel Norman2c99c5b2019-03-07 13:01:48 -080048
Bill Peckhame9eb5f92019-02-01 15:52:10 -080049 --output-target-files output-target-files-package
Daniel Normanfdb38812019-04-15 09:47:24 -070050 If provided, the output merged target files package. Also a zip archive.
51
52 --output-dir output-directory
53 If provided, the destination directory for saving merged files. Requires
54 the --output-item-list flag.
55 Can be provided alongside --output-target-files, or by itself.
56
57 --output-item-list output-item-list-file.
58 The optional path to a newline-separated config file that specifies the
59 file patterns to copy into the --output-dir. Required if providing
60 the --output-dir flag.
Daniel Normana4911da2019-03-15 14:36:21 -070061
Daniel Norman3b64ce12019-04-16 16:11:35 -070062 --output-ota output-ota-package
63 The output ota package. This is a zip archive. Use of this flag may
64 require passing the --path common flag; see common.py.
65
Daniel Norman1bd2a1d2019-04-18 12:32:18 -070066 --output-img output-img-package
67 The output img package, suitable for use with 'fastboot update'. Use of
68 this flag may require passing the --path common flag; see common.py.
69
Daniel Normanf0318252019-04-15 11:34:56 -070070 --output-super-empty output-super-empty-image
71 If provided, creates a super_empty.img file from the merged target
72 files package and saves it at this path.
73
Daniel Normana4911da2019-03-15 14:36:21 -070074 --rebuild_recovery
Bill Peckhame868aec2019-09-17 17:06:47 -070075 Deprecated; does nothing.
Bill Peckham364c1cc2019-03-29 18:27:23 -070076
Daniel Normanb0c75912020-09-24 14:30:21 -070077 --allow-duplicate-apkapex-keys
78 If provided, duplicate APK/APEX keys are ignored and the value from the
79 framework is used.
80
Bill Peckham364c1cc2019-03-29 18:27:23 -070081 --keep-tmp
82 Keep tempoary files for debugging purposes.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080083"""
84
85from __future__ import print_function
86
Bill Peckhame9eb5f92019-02-01 15:52:10 -080087import fnmatch
88import logging
89import os
Bill Peckham19c3feb2020-03-20 18:31:43 -070090import re
Daniel Normanfdb38812019-04-15 09:47:24 -070091import shutil
Bill Peckham540d91a2019-04-25 14:18:16 -070092import subprocess
Bill Peckhame9eb5f92019-02-01 15:52:10 -080093import sys
94import zipfile
95
Bill Peckhame9eb5f92019-02-01 15:52:10 -080096import add_img_to_target_files
Daniel Normanf0318252019-04-15 11:34:56 -070097import build_super_image
Yifan Hongade0d3f2019-08-21 16:37:11 -070098import check_target_files_vintf
Daniel Normanf0318252019-04-15 11:34:56 -070099import common
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700100import img_from_target_files
Daniel Norman3b64ce12019-04-16 16:11:35 -0700101import ota_from_target_files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800102
103logger = logging.getLogger(__name__)
Tao Bao2ad4b822019-06-27 16:52:12 -0700104
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800105OPTIONS = common.OPTIONS
Bill Peckhamcb848172020-04-03 12:50:47 -0700106# Always turn on verbose logging.
107OPTIONS.verbose = True
Daniel Normand5d70ea2019-06-05 15:13:43 -0700108OPTIONS.framework_target_files = None
109OPTIONS.framework_item_list = None
110OPTIONS.framework_misc_info_keys = None
111OPTIONS.vendor_target_files = None
112OPTIONS.vendor_item_list = None
Bill Peckhamf753e152019-02-19 18:02:46 -0800113OPTIONS.output_target_files = None
Daniel Normanfdb38812019-04-15 09:47:24 -0700114OPTIONS.output_dir = None
115OPTIONS.output_item_list = None
Daniel Norman3b64ce12019-04-16 16:11:35 -0700116OPTIONS.output_ota = None
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700117OPTIONS.output_img = None
Daniel Normanf0318252019-04-15 11:34:56 -0700118OPTIONS.output_super_empty = None
Bill Peckhame868aec2019-09-17 17:06:47 -0700119# TODO(b/132730255): Remove this option.
Daniel Normana4911da2019-03-15 14:36:21 -0700120OPTIONS.rebuild_recovery = False
Daniel Normanb0c75912020-09-24 14:30:21 -0700121# TODO(b/150582573): Remove this option.
122OPTIONS.allow_duplicate_apkapex_keys = False
Bill Peckhamf753e152019-02-19 18:02:46 -0800123OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800124
Bill Peckham19c3feb2020-03-20 18:31:43 -0700125# In an item list (framework or vendor), we may see entries that select whole
126# partitions. Such an entry might look like this 'SYSTEM/*' (e.g., for the
127# system partition). The following regex matches this and extracts the
128# partition name.
129
130PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/\*$')
131
Bill Peckham5c7b0342020-04-03 15:36:23 -0700132# In apexkeys.txt or apkcerts.txt, we will find partition tags on each entry in
133# the file. We use these partition tags to filter the entries in those files
134# from the two different target files packages to produce a merged apexkeys.txt
135# or apkcerts.txt file. A partition tag (e.g., for the product partition) looks
136# like this: 'partition="product"'. We use the group syntax grab the value of
137# the tag. We use non-greedy matching in case there are other fields on the
138# same line.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700139
Bill Peckham5c7b0342020-04-03 15:36:23 -0700140PARTITION_TAG_PATTERN = re.compile(r'partition="(.*?)"')
Bill Peckham19c3feb2020-03-20 18:31:43 -0700141
142# The sorting algorithm for apexkeys.txt and apkcerts.txt does not include the
143# ".apex" or ".apk" suffix, so we use the following pattern to extract a key.
144
145MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
146
Daniel Normand5d70ea2019-06-05 15:13:43 -0700147# DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
148# framework target files package as is, meaning these items will land in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800149# output target files package exactly as they appear in the input partial
Daniel Normand5d70ea2019-06-05 15:13:43 -0700150# framework target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800151
Daniel Normand5d70ea2019-06-05 15:13:43 -0700152DEFAULT_FRAMEWORK_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800153 'META/apkcerts.txt',
154 'META/filesystem_config.txt',
155 'META/root_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800156 'META/update_engine_config.txt',
157 'PRODUCT/*',
158 'ROOT/*',
159 'SYSTEM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700160)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800161
Daniel Normand5d70ea2019-06-05 15:13:43 -0700162# DEFAULT_FRAMEWORK_MISC_INFO_KEYS is a list of keys to obtain from the
Daniel Normandbbf5a32020-10-22 16:03:32 -0700163# framework instance of META/misc_info.txt. The remaining keys should come
164# from the vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800165
Daniel Normand5d70ea2019-06-05 15:13:43 -0700166DEFAULT_FRAMEWORK_MISC_INFO_KEYS = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800167 'avb_system_hashtree_enable',
168 'avb_system_add_hashtree_footer_args',
169 'avb_system_key_path',
170 'avb_system_algorithm',
171 'avb_system_rollback_index_location',
172 'avb_product_hashtree_enable',
173 'avb_product_add_hashtree_footer_args',
Justin Yun6151e3f2019-06-25 15:58:13 +0900174 'avb_system_ext_hashtree_enable',
175 'avb_system_ext_add_hashtree_footer_args',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800176 'system_root_image',
177 'root_dir',
178 'ab_update',
179 'default_system_dev_certificate',
180 'system_size',
Chris Gross203191b2020-05-30 02:39:12 +0000181 'building_system_image',
182 'building_system_ext_image',
183 'building_product_image',
Daniel Normanedf12472019-05-22 10:47:08 -0700184)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800185
Daniel Normand5d70ea2019-06-05 15:13:43 -0700186# DEFAULT_VENDOR_ITEM_LIST is a list of items to extract from the partial
187# vendor target files package as is, meaning these items will land in the output
188# target files package exactly as they appear in the input partial vendor target
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800189# files package.
190
Daniel Normand5d70ea2019-06-05 15:13:43 -0700191DEFAULT_VENDOR_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800192 'META/boot_filesystem_config.txt',
193 'META/otakeys.txt',
194 'META/releasetools.py',
195 'META/vendor_filesystem_config.txt',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800196 'BOOT/*',
197 'DATA/*',
198 'ODM/*',
199 'OTA/android-info.txt',
200 'PREBUILT_IMAGES/*',
201 'RADIO/*',
202 'VENDOR/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700203)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800204
Daniel Normanedf12472019-05-22 10:47:08 -0700205# The merge config lists should not attempt to extract items from both
206# builds for any of the following partitions. The partitions in
207# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700208# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700209
210SINGLE_BUILD_PARTITIONS = (
211 'BOOT/',
212 'DATA/',
213 'ODM/',
214 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900215 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700216 'RADIO/',
217 'RECOVERY/',
218 'ROOT/',
219 'SYSTEM/',
220 'SYSTEM_OTHER/',
221 'VENDOR/',
Yifan Hongcfb917a2020-05-07 14:58:20 -0700222 'VENDOR_DLKM/',
Yifan Hongf496f1b2020-07-15 16:52:59 -0700223 'ODM_DLKM/',
Daniel Normanedf12472019-05-22 10:47:08 -0700224)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800225
226
Chris Grossfabf50a2019-05-02 12:42:09 -0700227def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700228 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700229
Tao Bao2ad4b822019-06-27 16:52:12 -0700230 This function sorts the contents of the list or dict and then writes the
231 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700232
233 Args:
234 data: The list or dict to sort and write.
235 path: Path to the file to write the sorted values to. The file at path will
236 be overridden if it exists.
237 """
238 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700239 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700240 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
241 data, dict) else '{}\n'.format(entry)
242 output.write(out_str)
243
244
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800245def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700246 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800247
248 This function extracts from the specified target files zip archive into the
249 specified temporary directory, the items specified in the extract item list.
250
251 Args:
252 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800253 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700254 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800255 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800256 """
257
258 logger.info('extracting from %s', target_files)
259
260 # Filter the extract_item_list to remove any items that do not exist in the
261 # zip file. Otherwise, the extraction step will fail.
262
Daniel Norman4cc9df62019-07-18 10:11:07 -0700263 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800264 target_files_namelist = target_files_zipfile.namelist()
265
266 filtered_extract_item_list = []
267 for pattern in extract_item_list:
268 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
269 if not matching_namelist:
270 logger.warning('no match for %s', pattern)
271 else:
272 filtered_extract_item_list.append(pattern)
273
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800274 # Extract from target_files into target_files_temp_dir the
275 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800276
Daniel Normane5b134a2019-04-17 14:54:06 -0700277 common.UnzipToDir(target_files, target_files_temp_dir,
278 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800279
280
Daniel Normanfdb38812019-04-15 09:47:24 -0700281def copy_items(from_dir, to_dir, patterns):
282 """Similar to extract_items() except uses an input dir instead of zip."""
283 file_paths = []
284 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700285 file_paths.extend(
286 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
287 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700288
289 filtered_file_paths = set()
290 for pattern in patterns:
291 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
292
293 for file_path in filtered_file_paths:
294 original_file_path = os.path.join(from_dir, file_path)
295 copied_file_path = os.path.join(to_dir, file_path)
296 copied_file_dir = os.path.dirname(copied_file_path)
297 if not os.path.exists(copied_file_dir):
298 os.makedirs(copied_file_dir)
299 if os.path.islink(original_file_path):
300 os.symlink(os.readlink(original_file_path), copied_file_path)
301 else:
302 shutil.copyfile(original_file_path, copied_file_path)
303
304
Daniel Normand5d70ea2019-06-05 15:13:43 -0700305def validate_config_lists(framework_item_list, framework_misc_info_keys,
306 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700307 """Performs validations on the merge config lists.
308
309 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700310 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700311 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700312 framework_misc_info_keys: A list of keys to obtain from the framework
Daniel Normandbbf5a32020-10-22 16:03:32 -0700313 instance of META/misc_info.txt. The remaining keys should come from the
314 vendor instance.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700315 vendor_item_list: The list of items to extract from the partial vendor
316 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700317
318 Returns:
319 False if a validation fails, otherwise true.
320 """
Daniel Normanedf12472019-05-22 10:47:08 -0700321 has_error = False
322
Daniel Normand5d70ea2019-06-05 15:13:43 -0700323 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
324 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700325
Daniel Normand5d70ea2019-06-05 15:13:43 -0700326 combined_item_set = set(framework_item_list)
327 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700328
329 # Check that the merge config lists are not missing any item specified
330 # by the default config lists.
331 difference = default_combined_item_set.difference(combined_item_set)
332 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700333 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700334 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700335 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700336 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700337 has_error = True
338
Daniel Normandbbf5a32020-10-22 16:03:32 -0700339 # Check that partitions only come from one input.
Daniel Normanedf12472019-05-22 10:47:08 -0700340 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normandbbf5a32020-10-22 16:03:32 -0700341 image_path = 'IMAGES/{}.img'.format(partition.lower().replace('/', ''))
342 in_framework = (
343 any(item.startswith(partition) for item in framework_item_list) or
344 image_path in framework_item_list)
345 in_vendor = (
346 any(item.startswith(partition) for item in vendor_item_list) or
347 image_path in vendor_item_list)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700348 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700349 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700350 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900351 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700352 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700353 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700354
Daniel Normand5d70ea2019-06-05 15:13:43 -0700355 if ('dynamic_partition_list' in framework_misc_info_keys) or (
356 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700357 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700358 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700359 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700360
Daniel Normanedf12472019-05-22 10:47:08 -0700361 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700362
363
Daniel Normand5d70ea2019-06-05 15:13:43 -0700364def process_ab_partitions_txt(framework_target_files_temp_dir,
365 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700366 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700367 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800368
Tao Bao2ad4b822019-06-27 16:52:12 -0700369 This function merges the contents of the META/ab_partitions.txt files from the
370 framework directory and the vendor directory, placing the merged result in the
371 output directory. The precondition in that the files are already extracted.
372 The post condition is that the output META/ab_partitions.txt contains the
Daniel Normandbbf5a32020-10-22 16:03:32 -0700373 merged content. The format for each ab_partitions.txt is one partition name
374 per line. The output file contains the union of the partition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800375
376 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700377 framework_target_files_temp_dir: The name of a directory containing the
378 special items extracted from the framework target files package.
379 vendor_target_files_temp_dir: The name of a directory containing the special
380 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700381 output_target_files_temp_dir: The name of a directory that will be used to
382 create the output target files package after all the special cases are
383 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800384 """
385
Daniel Normand5d70ea2019-06-05 15:13:43 -0700386 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
387 'META', 'ab_partitions.txt')
388
389 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700390 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800391
Daniel Normand5d70ea2019-06-05 15:13:43 -0700392 with open(framework_ab_partitions_txt) as f:
393 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800394
Daniel Normand5d70ea2019-06-05 15:13:43 -0700395 with open(vendor_ab_partitions_txt) as f:
396 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800397
Daniel Normand5d70ea2019-06-05 15:13:43 -0700398 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800399
Daniel Normane5b134a2019-04-17 14:54:06 -0700400 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
401 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800402
Chris Grossfabf50a2019-05-02 12:42:09 -0700403 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800404
405
Daniel Normand5d70ea2019-06-05 15:13:43 -0700406def process_misc_info_txt(framework_target_files_temp_dir,
407 vendor_target_files_temp_dir,
408 output_target_files_temp_dir,
409 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700410 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800411
412 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700413 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800414 output directory. The precondition in that the files are already extracted.
415 The post condition is that the output META/misc_info.txt contains the merged
416 content.
417
418 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700419 framework_target_files_temp_dir: The name of a directory containing the
420 special items extracted from the framework target files package.
421 vendor_target_files_temp_dir: The name of a directory containing the special
422 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700423 output_target_files_temp_dir: The name of a directory that will be used to
424 create the output target files package after all the special cases are
425 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700426 framework_misc_info_keys: A list of keys to obtain from the framework
Daniel Normandbbf5a32020-10-22 16:03:32 -0700427 instance of META/misc_info.txt. The remaining keys should come from the
428 vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800429 """
430
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900431 misc_info_path = ['META', 'misc_info.txt']
432 framework_dict = common.LoadDictionaryFromFile(
433 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800434
Daniel Normand5d70ea2019-06-05 15:13:43 -0700435 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800436
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900437 merged_dict = common.LoadDictionaryFromFile(
438 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800439
Daniel Normand5d70ea2019-06-05 15:13:43 -0700440 # Replace certain values in merged_dict with values from
441 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800442
Daniel Normand5d70ea2019-06-05 15:13:43 -0700443 for key in framework_misc_info_keys:
444 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800445
Daniel Norman19b9fe92019-03-19 14:48:02 -0700446 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700447 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
448 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700449 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Norman55417142019-11-25 16:04:36 -0800450 framework_dict=framework_dict, vendor_dict=merged_dict)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700451 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700452 # Ensure that add_img_to_target_files rebuilds super split images for
453 # devices that retrofit dynamic partitions. This flag may have been set to
454 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700455 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700456
Daniel Normand5d70ea2019-06-05 15:13:43 -0700457 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700458 # depending on which dictionary the key came from.
459 # Only the file basename is required because all selinux_fc properties are
460 # replaced with the full path to the file under META/ when misc_info.txt is
461 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700462 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700463 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700464 merged_dict[key] = 'vendor_file_contexts.bin'
465 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700466 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700467 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700468
Daniel Normane5b134a2019-04-17 14:54:06 -0700469 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
470 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700471 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800472
473
Daniel Normand5d70ea2019-06-05 15:13:43 -0700474def process_dynamic_partitions_info_txt(framework_target_files_dir,
475 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700476 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700477 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700478
479 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700480 files from the framework directory and the vendor directory, placing the
481 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700482
Daniel Normand5d70ea2019-06-05 15:13:43 -0700483 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700484 directory does not exist.
485
486 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700487 framework_target_files_dir: The name of a directory containing the special
488 items extracted from the framework target files package.
489 vendor_target_files_dir: The name of a directory containing the special
490 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700491 output_target_files_dir: The name of a directory that will be used to create
492 the output target files package after all the special cases are processed.
493 """
494
495 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700496 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700497 'dynamic_partitions_info.txt')):
498 return
499
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900500 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700501
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900502 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
503 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
504 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
505 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700506
Daniel Normanbfc51ef2019-07-24 14:34:54 -0700507 merged_dynamic_partitions_dict = common.MergeDynamicPartitionInfoDicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700508 framework_dict=framework_dynamic_partitions_dict,
Daniel Norman55417142019-11-25 16:04:36 -0800509 vendor_dict=vendor_dynamic_partitions_dict)
Daniel Normana61cde02019-05-03 14:19:13 -0700510
511 output_dynamic_partitions_info_txt = os.path.join(
512 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700513 write_sorted_data(
514 data=merged_dynamic_partitions_dict,
515 path=output_dynamic_partitions_info_txt)
516
517
Bill Peckham19c3feb2020-03-20 18:31:43 -0700518def item_list_to_partition_set(item_list):
519 """Converts a target files item list to a partition set.
520
521 The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
522 'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
523 directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
524 contents of a partition of the same name. Other items in the list, such as the
525 'OTA' example contain metadata. This function iterates such a list, returning
526 a set that contains the partition entries.
527
528 Args:
529 item_list: A list of items in a target files package.
Daniel Normanb0c75912020-09-24 14:30:21 -0700530
Bill Peckham19c3feb2020-03-20 18:31:43 -0700531 Returns:
532 A set of partitions extracted from the list of items.
533 """
534
535 partition_set = set()
536
537 for item in item_list:
538 match = PARTITION_ITEM_PATTERN.search(item.strip())
539 partition_tag = match.group(1).lower() if match else None
540
541 if partition_tag:
542 partition_set.add(partition_tag)
543
544 return partition_set
545
546
Daniel Normand5d70ea2019-06-05 15:13:43 -0700547def process_apex_keys_apk_certs_common(framework_target_files_dir,
548 vendor_target_files_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700549 output_target_files_dir,
550 framework_partition_set,
551 vendor_partition_set, file_name):
Tao Bao2ad4b822019-06-27 16:52:12 -0700552 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700553
554 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700555 META/apkcerts.txt files from the framework directory and the vendor directory,
556 placing the merged result in the output directory. The precondition in that
557 the files are already extracted. The post condition is that the output
558 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700559
560 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700561 framework_target_files_dir: The name of a directory containing the special
562 items extracted from the framework target files package.
563 vendor_target_files_dir: The name of a directory containing the special
564 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700565 output_target_files_dir: The name of a directory that will be used to create
566 the output target files package after all the special cases are processed.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700567 framework_partition_set: Partitions that are considered framework
568 partitions. Used to filter apexkeys.txt and apkcerts.txt.
569 vendor_partition_set: Partitions that are considered vendor partitions. Used
570 to filter apexkeys.txt and apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700571 file_name: The name of the file to merge. One of apkcerts.txt or
572 apexkeys.txt.
573 """
574
575 def read_helper(d):
576 temp = {}
577 file_path = os.path.join(d, 'META', file_name)
578 with open(file_path) as f:
579 for line in f:
580 if line.strip():
Bill Peckham19c3feb2020-03-20 18:31:43 -0700581 name = line.split()[0]
582 match = MODULE_KEY_PATTERN.search(name)
583 temp[match.group(1)] = line.strip()
Chris Grossfabf50a2019-05-02 12:42:09 -0700584 return temp
585
Daniel Normand5d70ea2019-06-05 15:13:43 -0700586 framework_dict = read_helper(framework_target_files_dir)
587 vendor_dict = read_helper(vendor_target_files_dir)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700588 merged_dict = {}
Chris Grossfabf50a2019-05-02 12:42:09 -0700589
Bill Peckham19c3feb2020-03-20 18:31:43 -0700590 def filter_into_merged_dict(item_dict, partition_set):
591 for key, value in item_dict.items():
592 match = PARTITION_TAG_PATTERN.search(value)
593
594 if match is None:
595 raise ValueError('Entry missing partition tag: %s' % value)
596
597 partition_tag = match.group(1)
598
599 if partition_tag in partition_set:
600 if key in merged_dict:
Daniel Normanb0c75912020-09-24 14:30:21 -0700601 if OPTIONS.allow_duplicate_apkapex_keys:
602 # TODO(b/150582573) Always raise on duplicates.
603 logger.warning('Duplicate key %s' % key)
604 continue
605 else:
606 raise ValueError('Duplicate key %s' % key)
Bill Peckham19c3feb2020-03-20 18:31:43 -0700607
608 merged_dict[key] = value
609
610 filter_into_merged_dict(framework_dict, framework_partition_set)
611 filter_into_merged_dict(vendor_dict, vendor_partition_set)
Chris Grossfabf50a2019-05-02 12:42:09 -0700612
613 output_file = os.path.join(output_target_files_dir, 'META', file_name)
614
Bill Peckham19c3feb2020-03-20 18:31:43 -0700615 # The following code is similar to write_sorted_data, but different enough
616 # that we couldn't use that function. We need the output to be sorted by the
617 # basename of the apex/apk (without the ".apex" or ".apk" suffix). This
618 # allows the sort to be consistent with the framework/vendor input data and
619 # eases comparison of input data with merged data.
620 with open(output_file, 'w') as output:
621 for key in sorted(merged_dict.keys()):
622 out_str = merged_dict[key] + '\n'
623 output.write(out_str)
Daniel Normana61cde02019-05-03 14:19:13 -0700624
625
Daniel Normand5d70ea2019-06-05 15:13:43 -0700626def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700627 output_target_files_dir):
628 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700629 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
630 'framework_file_contexts.bin')
631 if not os.path.exists(framework_fc_path):
632 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
633 'file_contexts.bin')
634 if not os.path.exists(framework_fc_path):
635 raise ValueError('Missing framework file_contexts.bin.')
636 shutil.copyfile(
637 framework_fc_path,
638 os.path.join(output_target_files_dir, 'META',
639 'framework_file_contexts.bin'))
640
641 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
642 'vendor_file_contexts.bin')
643 if not os.path.exists(vendor_fc_path):
644 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700645 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700646 if not os.path.exists(vendor_fc_path):
647 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700648 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700649 vendor_fc_path,
650 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700651
652
Daniel Normand5d70ea2019-06-05 15:13:43 -0700653def process_special_cases(framework_target_files_temp_dir,
654 vendor_target_files_temp_dir,
655 output_target_files_temp_dir,
Daniel Normanb0c75912020-09-24 14:30:21 -0700656 framework_misc_info_keys, framework_partition_set,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700657 vendor_partition_set):
Tao Bao2ad4b822019-06-27 16:52:12 -0700658 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800659
660 Certain files in the output target files package require special-case
661 processing. This function performs all that special-case processing.
662
663 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700664 framework_target_files_temp_dir: The name of a directory containing the
665 special items extracted from the framework target files package.
666 vendor_target_files_temp_dir: The name of a directory containing the special
667 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700668 output_target_files_temp_dir: The name of a directory that will be used to
669 create the output target files package after all the special cases are
670 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700671 framework_misc_info_keys: A list of keys to obtain from the framework
Daniel Normandbbf5a32020-10-22 16:03:32 -0700672 instance of META/misc_info.txt. The remaining keys should come from the
673 vendor instance.
Bill Peckham19c3feb2020-03-20 18:31:43 -0700674 framework_partition_set: Partitions that are considered framework
675 partitions. Used to filter apexkeys.txt and apkcerts.txt.
676 vendor_partition_set: Partitions that are considered vendor partitions. Used
677 to filter apexkeys.txt and apkcerts.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800678 """
679
Daniel Normand5d70ea2019-06-05 15:13:43 -0700680 if 'ab_update' in framework_misc_info_keys:
Bill Peckham364c1cc2019-03-29 18:27:23 -0700681 process_ab_partitions_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700682 framework_target_files_temp_dir=framework_target_files_temp_dir,
683 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700684 output_target_files_temp_dir=output_target_files_temp_dir)
685
Daniel Norman72c626f2019-05-13 15:58:14 -0700686 copy_file_contexts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700687 framework_target_files_dir=framework_target_files_temp_dir,
688 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700689 output_target_files_dir=output_target_files_temp_dir)
690
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800691 process_misc_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700692 framework_target_files_temp_dir=framework_target_files_temp_dir,
693 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800694 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700695 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800696
Daniel Normana61cde02019-05-03 14:19:13 -0700697 process_dynamic_partitions_info_txt(
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,
Daniel Norman714bd122019-05-08 16:20:02 -0700700 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700701
Chris Grossfabf50a2019-05-02 12:42:09 -0700702 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700703 framework_target_files_dir=framework_target_files_temp_dir,
704 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700705 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700706 framework_partition_set=framework_partition_set,
707 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700708 file_name='apkcerts.txt')
709
710 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700711 framework_target_files_dir=framework_target_files_temp_dir,
712 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700713 output_target_files_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700714 framework_partition_set=framework_partition_set,
715 vendor_partition_set=vendor_partition_set,
Chris Grossfabf50a2019-05-02 12:42:09 -0700716 file_name='apexkeys.txt')
717
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800718
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900719def create_merged_package(temp_dir, framework_target_files, framework_item_list,
720 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700721 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700722 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800723
724 Args:
725 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700726 input target files packages, and also a scratch directory that we use for
727 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700728 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700729 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700730 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700731 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700732 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700733 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700734 vendor_target_files: The name of the zip archive containing the vendor
735 partial target files package.
736 vendor_item_list: The list of items to extract from the partial vendor
737 target files package as is, meaning these items will land in the output
738 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700739 target files package.
Daniel Normandbbf5a32020-10-22 16:03:32 -0700740 framework_misc_info_keys: A list of keys to obtain from the framework
741 instance of META/misc_info.txt. The remaining keys should come from the
742 vendor instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700743 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700744 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800745
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900746 Returns:
747 Path to merged package under temp directory.
748 """
Daniel Normandbbf5a32020-10-22 16:03:32 -0700749 # Extract "as is" items from the input framework and vendor partial target
750 # files packages directly into the output temporary directory, since these items
751 # do not need special case processing.
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800752
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800753 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
Bill Peckham889b0c62019-02-21 18:53:37 -0800754 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700755 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800756 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700757 extract_item_list=framework_item_list)
Bill Peckham889b0c62019-02-21 18:53:37 -0800758 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700759 target_files=vendor_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800760 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700761 extract_item_list=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800762
Daniel Normandbbf5a32020-10-22 16:03:32 -0700763 # Perform special case processing on META/* items.
764 # After this function completes successfully, all the files we need to create
765 # the output target files package are in place.
766 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
767 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700768 extract_items(
769 target_files=framework_target_files,
770 target_files_temp_dir=framework_target_files_temp_dir,
Daniel Normandbbf5a32020-10-22 16:03:32 -0700771 extract_item_list=('META/*',))
Bill Peckham889b0c62019-02-21 18:53:37 -0800772 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700773 target_files=vendor_target_files,
774 target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Normandbbf5a32020-10-22 16:03:32 -0700775 extract_item_list=('META/*',))
Bill Peckham889b0c62019-02-21 18:53:37 -0800776 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700777 framework_target_files_temp_dir=framework_target_files_temp_dir,
778 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800779 output_target_files_temp_dir=output_target_files_temp_dir,
Bill Peckham19c3feb2020-03-20 18:31:43 -0700780 framework_misc_info_keys=framework_misc_info_keys,
781 framework_partition_set=item_list_to_partition_set(framework_item_list),
782 vendor_partition_set=item_list_to_partition_set(vendor_item_list))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800783
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900784 return output_target_files_temp_dir
785
786
787def generate_images(target_files_dir, rebuild_recovery):
788 """Generate images from target files.
789
790 This function takes merged output temporary directory and create images
791 from it.
792
793 Args:
794 target_files_dir: Path to merged temp directory.
795 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
796 devices and write it to the system image.
797 """
798
799 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800800
Daniel Normandbbf5a32020-10-22 16:03:32 -0700801 add_img_args = [
802 '--verbose',
803 '--add_missing',
804 ]
Bill Peckhame868aec2019-09-17 17:06:47 -0700805 # TODO(b/132730255): Remove this if statement.
Daniel Normana4911da2019-03-15 14:36:21 -0700806 if rebuild_recovery:
807 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900808 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800809
810 add_img_to_target_files.main(add_img_args)
811
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900812
813def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700814 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900815
816 Args:
817 target_dir: Path to the target file package which contains misc_info.txt for
818 detailed information for super image.
819 output_super_empty: If provided, copies a super_empty.img file from the
820 target files package to this path.
821 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700822 # Create super_empty.img using the merged misc_info.txt.
823
Daniel Norman4cc9df62019-07-18 10:11:07 -0700824 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700825
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900826 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
827 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700828
829 if use_dynamic_partitions != 'true' and output_super_empty:
830 raise ValueError(
831 'Building super_empty.img requires use_dynamic_partitions=true.')
832 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700833 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700834 build_super_image_args = [
835 misc_info_txt,
836 super_empty_img,
837 ]
838 build_super_image.main(build_super_image_args)
839
840 # Copy super_empty.img to the user-provided output_super_empty location.
841 if output_super_empty:
842 shutil.copyfile(super_empty_img, output_super_empty)
843
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700844
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900845def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700846 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900847
848 Args:
849 output_file: The name of the zip archive target files package.
850 source_dir: The target directory contains package to be archived.
851 temp_dir: Path to temporary directory for any intermediate files.
852 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800853 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900854 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700855 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800856
Daniel Normandbbf5a32020-10-22 16:03:32 -0700857 def files_from_path(target_path, extra_args=None):
858 """Gets files under the given path and return a sorted list."""
859 find_command = ['find', target_path] + (extra_args or [])
860 find_process = common.Run(
861 find_command, stdout=subprocess.PIPE, verbose=False)
862 return common.RunAndCheckOutput(['sort'],
863 stdin=find_process.stdout,
864 verbose=False)
865
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900866 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700867 other_content = files_from_path(
868 source_dir,
869 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800870
Tao Bao2ad4b822019-06-27 16:52:12 -0700871 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800872 f.write(meta_content)
873 f.write(other_content)
874
875 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800876 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800877 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700878 '-o',
879 output_zip,
880 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900881 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700882 '-l',
883 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800884 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900885
886 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800887 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900888 logger.info('finished creating %s', output_file)
889
890 return output_zip
891
892
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900893def merge_target_files(temp_dir, framework_target_files, framework_item_list,
894 framework_misc_info_keys, vendor_target_files,
895 vendor_item_list, output_target_files, output_dir,
896 output_item_list, output_ota, output_img,
897 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700898 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900899
900 This function takes framework and vendor target files packages as input,
901 performs various file extractions, special case processing, and finally
902 creates a merged zip archive as output.
903
904 Args:
905 temp_dir: The name of a directory we use when we extract items from the
906 input target files packages, and also a scratch directory that we use for
907 temporary files.
908 framework_target_files: The name of the zip archive containing the framework
909 partial target files package.
910 framework_item_list: The list of items to extract from the partial framework
911 target files package as is, meaning these items will land in the output
912 target files package exactly as they appear in the input partial framework
913 target files package.
Daniel Normandbbf5a32020-10-22 16:03:32 -0700914 framework_misc_info_keys: A list of keys to obtain from the framework
915 instance of META/misc_info.txt. The remaining keys should come from the
916 vendor instance.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900917 vendor_target_files: The name of the zip archive containing the vendor
918 partial target files package.
919 vendor_item_list: The list of items to extract from the partial vendor
920 target files package as is, meaning these items will land in the output
921 target files package exactly as they appear in the input partial vendor
922 target files package.
923 output_target_files: The name of the output zip archive target files package
924 created by merging framework and vendor.
925 output_dir: The destination directory for saving merged files.
926 output_item_list: The list of items to copy into the output_dir.
927 output_ota: The name of the output zip archive ota package.
928 output_img: The name of the output zip archive img package.
929 output_super_empty: If provided, creates a super_empty.img file from the
930 merged target files package and saves it at this path.
931 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
932 devices and write it to the system image.
933 """
934
935 logger.info('starting: merge framework %s and vendor %s into output %s',
936 framework_target_files, vendor_target_files, output_target_files)
937
938 output_target_files_temp_dir = create_merged_package(
939 temp_dir, framework_target_files, framework_item_list,
940 vendor_target_files, vendor_item_list, framework_misc_info_keys,
941 rebuild_recovery)
942
Yifan Hongade0d3f2019-08-21 16:37:11 -0700943 if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
Daniel Normanb0c75912020-09-24 14:30:21 -0700944 raise RuntimeError('Incompatible VINTF metadata')
Yifan Hongade0d3f2019-08-21 16:37:11 -0700945
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900946 generate_images(output_target_files_temp_dir, rebuild_recovery)
947
948 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
949
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900950 # Finally, create the output target files zip archive and/or copy the
951 # output items to the output target files directory.
952
953 if output_dir:
954 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
955
956 if not output_target_files:
957 return
958
959 output_zip = create_target_files_archive(output_target_files,
960 output_target_files_temp_dir,
961 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800962
Daniel Norman74eb74b2019-09-18 14:01:48 -0700963 # Create the IMG package from the merged target files package.
964
965 if output_img:
966 img_from_target_files.main([output_zip, output_img])
967
Daniel Norman3b64ce12019-04-16 16:11:35 -0700968 # Create the OTA package from the merged target files package.
969
970 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700971 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -0700972
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700973
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800974def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -0700975 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800976
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800977 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800978 directory. It also cleans up the temporary directory.
979
980 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -0700981 func: The function to call. Should accept one parameter, the path to the
982 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800983 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800984 """
985
986 # Create a temporary directory. This will serve as the parent of directories
987 # we use when we extract items from the input target files packages, and also
988 # a scratch directory that we use for temporary files.
989
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800990 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
991
992 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800993 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800994 finally:
995 if keep_tmp:
996 logger.info('keeping %s', temp_dir)
997 else:
998 common.Cleanup()
999
1000
1001def main():
1002 """The main function.
1003
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001004 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001005 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001006 """
1007
1008 common.InitLogging()
1009
Bill Peckhamf753e152019-02-19 18:02:46 -08001010 def option_handler(o, a):
1011 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001012 logger.warning(
1013 '--system-target-files has been renamed to --framework-target-files')
1014 OPTIONS.framework_target_files = a
1015 elif o == '--framework-target-files':
1016 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001017 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001018 logger.warning(
1019 '--system-item-list has been renamed to --framework-item-list')
1020 OPTIONS.framework_item_list = a
1021 elif o == '--framework-item-list':
1022 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001023 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001024 logger.warning('--system-misc-info-keys has been renamed to '
1025 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001026 OPTIONS.framework_misc_info_keys = a
1027 elif o == '--framework-misc-info-keys':
1028 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001029 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001030 logger.warning(
1031 '--other-target-files has been renamed to --vendor-target-files')
1032 OPTIONS.vendor_target_files = a
1033 elif o == '--vendor-target-files':
1034 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001035 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001036 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1037 OPTIONS.vendor_item_list = a
1038 elif o == '--vendor-item-list':
1039 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001040 elif o == '--output-target-files':
1041 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001042 elif o == '--output-dir':
1043 OPTIONS.output_dir = a
1044 elif o == '--output-item-list':
1045 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001046 elif o == '--output-ota':
1047 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001048 elif o == '--output-img':
1049 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001050 elif o == '--output-super-empty':
1051 OPTIONS.output_super_empty = a
Daniel Normanb0c75912020-09-24 14:30:21 -07001052 elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
Daniel Normana4911da2019-03-15 14:36:21 -07001053 OPTIONS.rebuild_recovery = True
Daniel Normanb0c75912020-09-24 14:30:21 -07001054 elif o == '--allow-duplicate-apkapex-keys':
1055 OPTIONS.allow_duplicate_apkapex_keys = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001056 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001057 OPTIONS.keep_tmp = True
1058 else:
1059 return False
1060 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001061
Bill Peckhamf753e152019-02-19 18:02:46 -08001062 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001063 sys.argv[1:],
1064 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001065 extra_long_opts=[
1066 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001067 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001068 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001069 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001070 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001071 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001072 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001073 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001074 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001075 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001076 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001077 'output-dir=',
1078 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001079 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001080 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001081 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001082 'rebuild_recovery',
Daniel Normanb0c75912020-09-24 14:30:21 -07001083 'allow-duplicate-apkapex-keys',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001084 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001085 ],
1086 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001087
Tao Bao2ad4b822019-06-27 16:52:12 -07001088 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001089 if (args or OPTIONS.framework_target_files is None or
1090 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001091 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1092 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001093 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001094 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001095
Daniel Normand5d70ea2019-06-05 15:13:43 -07001096 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001097 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001098 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001099 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001100
Daniel Normand5d70ea2019-06-05 15:13:43 -07001101 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001102 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001103 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001104 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001105 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001106
Daniel Normand5d70ea2019-06-05 15:13:43 -07001107 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001108 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001109 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001110 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001111
Daniel Normanfdb38812019-04-15 09:47:24 -07001112 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001113 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001114 else:
1115 output_item_list = None
1116
Daniel Normane5964522019-03-19 10:32:03 -07001117 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001118 framework_item_list=framework_item_list,
1119 framework_misc_info_keys=framework_misc_info_keys,
1120 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001121 sys.exit(1)
1122
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001123 call_func_with_temp_dir(
1124 lambda temp_dir: merge_target_files(
1125 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001126 framework_target_files=OPTIONS.framework_target_files,
1127 framework_item_list=framework_item_list,
1128 framework_misc_info_keys=framework_misc_info_keys,
1129 vendor_target_files=OPTIONS.vendor_target_files,
1130 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001131 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001132 output_dir=OPTIONS.output_dir,
1133 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001134 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001135 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001136 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001137 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001138
1139
1140if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001141 main()