blob: 7343f389b30d0187473f115e690f0d049cb5d6e4 [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
71 Rebuild the recovery patch used by non-A/B devices and write it to the
72 system image.
Bill Peckham364c1cc2019-03-29 18:27:23 -070073
74 --keep-tmp
75 Keep tempoary files for debugging purposes.
Bill Peckhame9eb5f92019-02-01 15:52:10 -080076"""
77
78from __future__ import print_function
79
Bill Peckhame9eb5f92019-02-01 15:52:10 -080080import fnmatch
81import logging
82import os
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
90import common
Daniel Norman1bd2a1d2019-04-18 12:32:18 -070091import img_from_target_files
Daniel Norman3b64ce12019-04-16 16:11:35 -070092import ota_from_target_files
Bill Peckhame9eb5f92019-02-01 15:52:10 -080093
94logger = logging.getLogger(__name__)
Tao Bao2ad4b822019-06-27 16:52:12 -070095
Bill Peckhame9eb5f92019-02-01 15:52:10 -080096OPTIONS = common.OPTIONS
97OPTIONS.verbose = True
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
Daniel Normana4911da2019-03-15 14:36:21 -0700109OPTIONS.rebuild_recovery = False
Bill Peckhamf753e152019-02-19 18:02:46 -0800110OPTIONS.keep_tmp = False
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800111
Daniel Normand5d70ea2019-06-05 15:13:43 -0700112# DEFAULT_FRAMEWORK_ITEM_LIST is a list of items to extract from the partial
113# framework target files package as is, meaning these items will land in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800114# output target files package exactly as they appear in the input partial
Daniel Normand5d70ea2019-06-05 15:13:43 -0700115# framework target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800116
Daniel Normand5d70ea2019-06-05 15:13:43 -0700117DEFAULT_FRAMEWORK_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800118 'META/apkcerts.txt',
119 'META/filesystem_config.txt',
120 'META/root_filesystem_config.txt',
121 'META/system_manifest.xml',
122 'META/system_matrix.xml',
123 'META/update_engine_config.txt',
124 'PRODUCT/*',
125 'ROOT/*',
126 'SYSTEM/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700127)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800128
Daniel Normand5d70ea2019-06-05 15:13:43 -0700129# FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
130# partial framework target files package that need some special processing, such
131# as some sort of combination with items from the partial vendor target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800132# package.
133
Daniel Normand5d70ea2019-06-05 15:13:43 -0700134FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800135
Daniel Normand5d70ea2019-06-05 15:13:43 -0700136# DEFAULT_FRAMEWORK_MISC_INFO_KEYS is a list of keys to obtain from the
137# framework instance of META/misc_info.txt. The remaining keys from the
138# vendor instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800139
Daniel Normand5d70ea2019-06-05 15:13:43 -0700140DEFAULT_FRAMEWORK_MISC_INFO_KEYS = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800141 'avb_system_hashtree_enable',
142 'avb_system_add_hashtree_footer_args',
143 'avb_system_key_path',
144 'avb_system_algorithm',
145 'avb_system_rollback_index_location',
146 'avb_product_hashtree_enable',
147 'avb_product_add_hashtree_footer_args',
Justin Yun6151e3f2019-06-25 15:58:13 +0900148 'avb_system_ext_hashtree_enable',
149 'avb_system_ext_add_hashtree_footer_args',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800150 'system_root_image',
151 'root_dir',
152 'ab_update',
153 'default_system_dev_certificate',
154 'system_size',
Daniel Normanedf12472019-05-22 10:47:08 -0700155)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800156
Daniel Normand5d70ea2019-06-05 15:13:43 -0700157# DEFAULT_VENDOR_ITEM_LIST is a list of items to extract from the partial
158# vendor target files package as is, meaning these items will land in the output
159# target files package exactly as they appear in the input partial vendor target
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800160# files package.
161
Daniel Normand5d70ea2019-06-05 15:13:43 -0700162DEFAULT_VENDOR_ITEM_LIST = (
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800163 'META/boot_filesystem_config.txt',
164 'META/otakeys.txt',
165 'META/releasetools.py',
166 'META/vendor_filesystem_config.txt',
167 'META/vendor_manifest.xml',
168 'META/vendor_matrix.xml',
169 'BOOT/*',
170 'DATA/*',
171 'ODM/*',
172 'OTA/android-info.txt',
173 'PREBUILT_IMAGES/*',
174 'RADIO/*',
175 'VENDOR/*',
Daniel Normanedf12472019-05-22 10:47:08 -0700176)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800177
Daniel Normand5d70ea2019-06-05 15:13:43 -0700178# VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
179# partial vendor target files package that need some special processing, such as
180# some sort of combination with items from the partial framework target files
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800181# package.
182
Daniel Normand5d70ea2019-06-05 15:13:43 -0700183VENDOR_EXTRACT_SPECIAL_ITEM_LIST = ('META/*',)
Daniel Normanedf12472019-05-22 10:47:08 -0700184
185# The merge config lists should not attempt to extract items from both
186# builds for any of the following partitions. The partitions in
187# SINGLE_BUILD_PARTITIONS should come entirely from a single build (either
Daniel Normand5d70ea2019-06-05 15:13:43 -0700188# framework or vendor, but not both).
Daniel Normanedf12472019-05-22 10:47:08 -0700189
190SINGLE_BUILD_PARTITIONS = (
191 'BOOT/',
192 'DATA/',
193 'ODM/',
194 'PRODUCT/',
Justin Yun6151e3f2019-06-25 15:58:13 +0900195 'SYSTEM_EXT/',
Daniel Normanedf12472019-05-22 10:47:08 -0700196 'RADIO/',
197 'RECOVERY/',
198 'ROOT/',
199 'SYSTEM/',
200 'SYSTEM_OTHER/',
201 'VENDOR/',
202)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800203
204
Chris Grossfabf50a2019-05-02 12:42:09 -0700205def write_sorted_data(data, path):
Tao Bao2ad4b822019-06-27 16:52:12 -0700206 """Writes the sorted contents of either a list or dict to file.
Chris Grossfabf50a2019-05-02 12:42:09 -0700207
Tao Bao2ad4b822019-06-27 16:52:12 -0700208 This function sorts the contents of the list or dict and then writes the
209 resulting sorted contents to a file specified by path.
Chris Grossfabf50a2019-05-02 12:42:09 -0700210
211 Args:
212 data: The list or dict to sort and write.
213 path: Path to the file to write the sorted values to. The file at path will
214 be overridden if it exists.
215 """
216 with open(path, 'w') as output:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700217 for entry in sorted(data):
Chris Grossfabf50a2019-05-02 12:42:09 -0700218 out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
219 data, dict) else '{}\n'.format(entry)
220 output.write(out_str)
221
222
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800223def extract_items(target_files, target_files_temp_dir, extract_item_list):
Tao Bao2ad4b822019-06-27 16:52:12 -0700224 """Extracts items from target files to temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800225
226 This function extracts from the specified target files zip archive into the
227 specified temporary directory, the items specified in the extract item list.
228
229 Args:
230 target_files: The target files zip archive from which to extract items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800231 target_files_temp_dir: The temporary directory where the extracted items
Daniel Normane5b134a2019-04-17 14:54:06 -0700232 will land.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800233 extract_item_list: A list of items to extract.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800234 """
235
236 logger.info('extracting from %s', target_files)
237
238 # Filter the extract_item_list to remove any items that do not exist in the
239 # zip file. Otherwise, the extraction step will fail.
240
Daniel Norman4cc9df62019-07-18 10:11:07 -0700241 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zipfile:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800242 target_files_namelist = target_files_zipfile.namelist()
243
244 filtered_extract_item_list = []
245 for pattern in extract_item_list:
246 matching_namelist = fnmatch.filter(target_files_namelist, pattern)
247 if not matching_namelist:
248 logger.warning('no match for %s', pattern)
249 else:
250 filtered_extract_item_list.append(pattern)
251
Bill Peckham8ff3fbd2019-02-22 10:57:43 -0800252 # Extract from target_files into target_files_temp_dir the
253 # filtered_extract_item_list.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800254
Daniel Normane5b134a2019-04-17 14:54:06 -0700255 common.UnzipToDir(target_files, target_files_temp_dir,
256 filtered_extract_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800257
258
Daniel Normanfdb38812019-04-15 09:47:24 -0700259def copy_items(from_dir, to_dir, patterns):
260 """Similar to extract_items() except uses an input dir instead of zip."""
261 file_paths = []
262 for dirpath, _, filenames in os.walk(from_dir):
Daniel Normane5b134a2019-04-17 14:54:06 -0700263 file_paths.extend(
264 os.path.relpath(path=os.path.join(dirpath, filename), start=from_dir)
265 for filename in filenames)
Daniel Normanfdb38812019-04-15 09:47:24 -0700266
267 filtered_file_paths = set()
268 for pattern in patterns:
269 filtered_file_paths.update(fnmatch.filter(file_paths, pattern))
270
271 for file_path in filtered_file_paths:
272 original_file_path = os.path.join(from_dir, file_path)
273 copied_file_path = os.path.join(to_dir, file_path)
274 copied_file_dir = os.path.dirname(copied_file_path)
275 if not os.path.exists(copied_file_dir):
276 os.makedirs(copied_file_dir)
277 if os.path.islink(original_file_path):
278 os.symlink(os.readlink(original_file_path), copied_file_path)
279 else:
280 shutil.copyfile(original_file_path, copied_file_path)
281
282
Daniel Normand5d70ea2019-06-05 15:13:43 -0700283def validate_config_lists(framework_item_list, framework_misc_info_keys,
284 vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -0700285 """Performs validations on the merge config lists.
286
287 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700288 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700289 target files package as is.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700290 framework_misc_info_keys: A list of keys to obtain from the framework
291 instance of META/misc_info.txt. The remaining keys from the vendor
292 instance.
293 vendor_item_list: The list of items to extract from the partial vendor
294 target files package as is.
Daniel Normane5964522019-03-19 10:32:03 -0700295
296 Returns:
297 False if a validation fails, otherwise true.
298 """
Daniel Normanedf12472019-05-22 10:47:08 -0700299 has_error = False
300
Daniel Normand5d70ea2019-06-05 15:13:43 -0700301 default_combined_item_set = set(DEFAULT_FRAMEWORK_ITEM_LIST)
302 default_combined_item_set.update(DEFAULT_VENDOR_ITEM_LIST)
Daniel Normane5964522019-03-19 10:32:03 -0700303
Daniel Normand5d70ea2019-06-05 15:13:43 -0700304 combined_item_set = set(framework_item_list)
305 combined_item_set.update(vendor_item_list)
Daniel Normane5964522019-03-19 10:32:03 -0700306
307 # Check that the merge config lists are not missing any item specified
308 # by the default config lists.
309 difference = default_combined_item_set.difference(combined_item_set)
310 if difference:
Daniel Normane5b134a2019-04-17 14:54:06 -0700311 logger.error('Missing merge config items: %s', list(difference))
Daniel Normane5964522019-03-19 10:32:03 -0700312 logger.error('Please ensure missing items are in either the '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700313 'framework-item-list or vendor-item-list files provided to '
Daniel Normane5964522019-03-19 10:32:03 -0700314 'this script.')
Daniel Normanedf12472019-05-22 10:47:08 -0700315 has_error = True
316
317 for partition in SINGLE_BUILD_PARTITIONS:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700318 in_framework = any(
319 item.startswith(partition) for item in framework_item_list)
320 in_vendor = any(item.startswith(partition) for item in vendor_item_list)
321 if in_framework and in_vendor:
Daniel Normanedf12472019-05-22 10:47:08 -0700322 logger.error(
Tao Bao2ad4b822019-06-27 16:52:12 -0700323 'Cannot extract items from %s for both the framework and vendor'
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900324 ' builds. Please ensure only one merge config item list'
Tao Bao2ad4b822019-06-27 16:52:12 -0700325 ' includes %s.', partition, partition)
Daniel Normanedf12472019-05-22 10:47:08 -0700326 has_error = True
Daniel Normane5964522019-03-19 10:32:03 -0700327
Daniel Normand5d70ea2019-06-05 15:13:43 -0700328 if ('dynamic_partition_list' in framework_misc_info_keys) or (
329 'super_partition_groups' in framework_misc_info_keys):
Daniel Norman19b9fe92019-03-19 14:48:02 -0700330 logger.error('Dynamic partition misc info keys should come from '
Daniel Normand5d70ea2019-06-05 15:13:43 -0700331 'the vendor instance of META/misc_info.txt.')
Daniel Normanedf12472019-05-22 10:47:08 -0700332 has_error = True
Daniel Norman19b9fe92019-03-19 14:48:02 -0700333
Daniel Normanedf12472019-05-22 10:47:08 -0700334 return not has_error
Daniel Normane5964522019-03-19 10:32:03 -0700335
336
Daniel Normand5d70ea2019-06-05 15:13:43 -0700337def process_ab_partitions_txt(framework_target_files_temp_dir,
338 vendor_target_files_temp_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700339 output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700340 """Performs special processing for META/ab_partitions.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800341
Tao Bao2ad4b822019-06-27 16:52:12 -0700342 This function merges the contents of the META/ab_partitions.txt files from the
343 framework directory and the vendor directory, placing the merged result in the
344 output directory. The precondition in that the files are already extracted.
345 The post condition is that the output META/ab_partitions.txt contains the
346 merged content. The format for each ab_partitions.txt a one partition name per
347 line. The output file contains the union of the parition names.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800348
349 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700350 framework_target_files_temp_dir: The name of a directory containing the
351 special items extracted from the framework target files package.
352 vendor_target_files_temp_dir: The name of a directory containing the special
353 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700354 output_target_files_temp_dir: The name of a directory that will be used to
355 create the output target files package after all the special cases are
356 processed.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800357 """
358
Daniel Normand5d70ea2019-06-05 15:13:43 -0700359 framework_ab_partitions_txt = os.path.join(framework_target_files_temp_dir,
360 'META', 'ab_partitions.txt')
361
362 vendor_ab_partitions_txt = os.path.join(vendor_target_files_temp_dir, 'META',
Daniel Normane5b134a2019-04-17 14:54:06 -0700363 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800364
Daniel Normand5d70ea2019-06-05 15:13:43 -0700365 with open(framework_ab_partitions_txt) as f:
366 framework_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800367
Daniel Normand5d70ea2019-06-05 15:13:43 -0700368 with open(vendor_ab_partitions_txt) as f:
369 vendor_ab_partitions = f.read().splitlines()
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800370
Daniel Normand5d70ea2019-06-05 15:13:43 -0700371 output_ab_partitions = set(framework_ab_partitions + vendor_ab_partitions)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800372
Daniel Normane5b134a2019-04-17 14:54:06 -0700373 output_ab_partitions_txt = os.path.join(output_target_files_temp_dir, 'META',
374 'ab_partitions.txt')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800375
Chris Grossfabf50a2019-05-02 12:42:09 -0700376 write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800377
378
Bill Peckham364c1cc2019-03-29 18:27:23 -0700379def append_recovery_to_filesystem_config(output_target_files_temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700380 """Performs special processing for META/filesystem_config.txt.
Bill Peckham364c1cc2019-03-29 18:27:23 -0700381
Tao Bao2ad4b822019-06-27 16:52:12 -0700382 This function appends recovery information to META/filesystem_config.txt so
383 that recovery patch regeneration will succeed.
Bill Peckham364c1cc2019-03-29 18:27:23 -0700384
385 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -0700386 output_target_files_temp_dir: The name of a directory that will be used to
387 create the output target files package after all the special cases are
388 processed. We find filesystem_config.txt here.
Bill Peckham364c1cc2019-03-29 18:27:23 -0700389 """
390
Daniel Normane5b134a2019-04-17 14:54:06 -0700391 filesystem_config_txt = os.path.join(output_target_files_temp_dir, 'META',
392 'filesystem_config.txt')
Bill Peckham364c1cc2019-03-29 18:27:23 -0700393
394 with open(filesystem_config_txt, 'a') as f:
395 # TODO(bpeckham) this data is hard coded. It should be generated
396 # programmatically.
Daniel Normane5b134a2019-04-17 14:54:06 -0700397 f.write('system/bin/install-recovery.sh 0 0 750 '
398 'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
399 f.write('system/recovery-from-boot.p 0 0 644 '
400 'selabel=u:object_r:system_file:s0 capabilities=0x0\n')
401 f.write('system/etc/recovery.img 0 0 440 '
402 'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
Bill Peckham364c1cc2019-03-29 18:27:23 -0700403
404
Daniel Normand5d70ea2019-06-05 15:13:43 -0700405def merge_dynamic_partition_info_dicts(framework_dict,
406 vendor_dict,
Daniel Normana61cde02019-05-03 14:19:13 -0700407 include_dynamic_partition_list=True,
408 size_prefix='',
409 size_suffix='',
410 list_prefix='',
411 list_suffix=''):
412 """Merges dynamic partition info variables.
413
414 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700415 framework_dict: The dictionary of dynamic partition info variables from the
416 partial framework target files.
417 vendor_dict: The dictionary of dynamic partition info variables from the
418 partial vendor target files.
Daniel Normana61cde02019-05-03 14:19:13 -0700419 include_dynamic_partition_list: If true, merges the dynamic_partition_list
420 variable. Not all use cases need this variable merged.
421 size_prefix: The prefix in partition group size variables that precedes the
422 name of the partition group. For example, partition group 'group_a' with
423 corresponding size variable 'super_group_a_group_size' would have the
424 size_prefix 'super_'.
425 size_suffix: Similar to size_prefix but for the variable's suffix. For
426 example, 'super_group_a_group_size' would have size_suffix '_group_size'.
427 list_prefix: Similar to size_prefix but for the partition group's
428 partition_list variable.
429 list_suffix: Similar to size_suffix but for the partition group's
430 partition_list variable.
431
432 Returns:
433 The merged dynamic partition info dictionary.
434 """
435 merged_dict = {}
Daniel Normand5d70ea2019-06-05 15:13:43 -0700436 # Partition groups and group sizes are defined by the vendor dict because
437 # these values may vary for each board that uses a shared system image.
438 merged_dict['super_partition_groups'] = vendor_dict['super_partition_groups']
Daniel Normana61cde02019-05-03 14:19:13 -0700439 if include_dynamic_partition_list:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700440 framework_dynamic_partition_list = framework_dict.get(
441 'dynamic_partition_list', '')
442 vendor_dynamic_partition_list = vendor_dict.get('dynamic_partition_list',
Daniel Normana61cde02019-05-03 14:19:13 -0700443 '')
Daniel Normana61cde02019-05-03 14:19:13 -0700444 merged_dict['dynamic_partition_list'] = (
Daniel Normand5d70ea2019-06-05 15:13:43 -0700445 '%s %s' % (framework_dynamic_partition_list,
446 vendor_dynamic_partition_list)).strip()
Daniel Normana61cde02019-05-03 14:19:13 -0700447 for partition_group in merged_dict['super_partition_groups'].split(' '):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700448 # Set the partition group's size using the value from the vendor dict.
Daniel Normana61cde02019-05-03 14:19:13 -0700449 key = '%s%s%s' % (size_prefix, partition_group, size_suffix)
Daniel Normand5d70ea2019-06-05 15:13:43 -0700450 if key not in vendor_dict:
451 raise ValueError('Vendor dict does not contain required key %s.' % key)
452 merged_dict[key] = vendor_dict[key]
Daniel Normana61cde02019-05-03 14:19:13 -0700453
454 # Set the partition group's partition list using a concatenation of the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700455 # framework and vendor partition lists.
Daniel Normana61cde02019-05-03 14:19:13 -0700456 key = '%s%s%s' % (list_prefix, partition_group, list_suffix)
457 merged_dict[key] = (
Daniel Normand5d70ea2019-06-05 15:13:43 -0700458 '%s %s' %
459 (framework_dict.get(key, ''), vendor_dict.get(key, ''))).strip()
Daniel Normana61cde02019-05-03 14:19:13 -0700460 return merged_dict
461
462
Daniel Normand5d70ea2019-06-05 15:13:43 -0700463def process_misc_info_txt(framework_target_files_temp_dir,
464 vendor_target_files_temp_dir,
465 output_target_files_temp_dir,
466 framework_misc_info_keys):
Tao Bao2ad4b822019-06-27 16:52:12 -0700467 """Performs special processing for META/misc_info.txt.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800468
469 This function merges the contents of the META/misc_info.txt files from the
Daniel Normand5d70ea2019-06-05 15:13:43 -0700470 framework directory and the vendor directory, placing the merged result in the
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800471 output directory. The precondition in that the files are already extracted.
472 The post condition is that the output META/misc_info.txt contains the merged
473 content.
474
475 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700476 framework_target_files_temp_dir: The name of a directory containing the
477 special items extracted from the framework target files package.
478 vendor_target_files_temp_dir: The name of a directory containing the special
479 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700480 output_target_files_temp_dir: The name of a directory that will be used to
481 create the output target files package after all the special cases are
482 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700483 framework_misc_info_keys: A list of keys to obtain from the framework
484 instance of META/misc_info.txt. The remaining keys from the vendor
485 instance.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800486 """
487
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900488 misc_info_path = ['META', 'misc_info.txt']
489 framework_dict = common.LoadDictionaryFromFile(
490 os.path.join(framework_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800491
Daniel Normand5d70ea2019-06-05 15:13:43 -0700492 # We take most of the misc info from the vendor target files.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800493
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900494 merged_dict = common.LoadDictionaryFromFile(
495 os.path.join(vendor_target_files_temp_dir, *misc_info_path))
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800496
Daniel Normand5d70ea2019-06-05 15:13:43 -0700497 # Replace certain values in merged_dict with values from
498 # framework_dict.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800499
Daniel Normand5d70ea2019-06-05 15:13:43 -0700500 for key in framework_misc_info_keys:
501 merged_dict[key] = framework_dict[key]
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800502
Daniel Norman19b9fe92019-03-19 14:48:02 -0700503 # Merge misc info keys used for Dynamic Partitions.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700504 if (merged_dict.get('use_dynamic_partitions') == 'true') and (
505 framework_dict.get('use_dynamic_partitions') == 'true'):
Daniel Normana61cde02019-05-03 14:19:13 -0700506 merged_dynamic_partitions_dict = merge_dynamic_partition_info_dicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700507 framework_dict=framework_dict,
508 vendor_dict=merged_dict,
Daniel Normana61cde02019-05-03 14:19:13 -0700509 size_prefix='super_',
510 size_suffix='_group_size',
511 list_prefix='super_',
512 list_suffix='_partition_list')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700513 merged_dict.update(merged_dynamic_partitions_dict)
Tao Bao48a2feb2019-06-28 11:00:05 -0700514 # Ensure that add_img_to_target_files rebuilds super split images for
515 # devices that retrofit dynamic partitions. This flag may have been set to
516 # false in the partial builds to prevent duplicate building of super.img.
Daniel Norman0bf940c2019-06-10 12:50:19 -0700517 merged_dict['build_super_partition'] = 'true'
Daniel Norman19b9fe92019-03-19 14:48:02 -0700518
Daniel Normand5d70ea2019-06-05 15:13:43 -0700519 # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
Daniel Norman72c626f2019-05-13 15:58:14 -0700520 # depending on which dictionary the key came from.
521 # Only the file basename is required because all selinux_fc properties are
522 # replaced with the full path to the file under META/ when misc_info.txt is
523 # loaded from target files for repacking. See common.py LoadInfoDict().
Daniel Normand5d70ea2019-06-05 15:13:43 -0700524 for key in merged_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700525 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700526 merged_dict[key] = 'vendor_file_contexts.bin'
527 for key in framework_dict:
Daniel Norman72c626f2019-05-13 15:58:14 -0700528 if key.endswith('_selinux_fc'):
Daniel Normand5d70ea2019-06-05 15:13:43 -0700529 merged_dict[key] = 'framework_file_contexts.bin'
Daniel Norman72c626f2019-05-13 15:58:14 -0700530
Daniel Normane5b134a2019-04-17 14:54:06 -0700531 output_misc_info_txt = os.path.join(output_target_files_temp_dir, 'META',
532 'misc_info.txt')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700533 write_sorted_data(data=merged_dict, path=output_misc_info_txt)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800534
535
Daniel Normand5d70ea2019-06-05 15:13:43 -0700536def process_dynamic_partitions_info_txt(framework_target_files_dir,
537 vendor_target_files_dir,
Daniel Normana61cde02019-05-03 14:19:13 -0700538 output_target_files_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700539 """Performs special processing for META/dynamic_partitions_info.txt.
Daniel Normana61cde02019-05-03 14:19:13 -0700540
541 This function merges the contents of the META/dynamic_partitions_info.txt
Daniel Normand5d70ea2019-06-05 15:13:43 -0700542 files from the framework directory and the vendor directory, placing the
543 merged result in the output directory.
Daniel Normana61cde02019-05-03 14:19:13 -0700544
Daniel Normand5d70ea2019-06-05 15:13:43 -0700545 This function does nothing if META/dynamic_partitions_info.txt from the vendor
Daniel Normana61cde02019-05-03 14:19:13 -0700546 directory does not exist.
547
548 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700549 framework_target_files_dir: The name of a directory containing the special
550 items extracted from the framework target files package.
551 vendor_target_files_dir: The name of a directory containing the special
552 items extracted from the vendor target files package.
Daniel Normana61cde02019-05-03 14:19:13 -0700553 output_target_files_dir: The name of a directory that will be used to create
554 the output target files package after all the special cases are processed.
555 """
556
557 if not os.path.exists(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700558 os.path.join(vendor_target_files_dir, 'META',
Daniel Normana61cde02019-05-03 14:19:13 -0700559 'dynamic_partitions_info.txt')):
560 return
561
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900562 dynamic_partitions_info_path = ['META', 'dynamic_partitions_info.txt']
Daniel Normana61cde02019-05-03 14:19:13 -0700563
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900564 framework_dynamic_partitions_dict = common.LoadDictionaryFromFile(
565 os.path.join(framework_target_files_dir, *dynamic_partitions_info_path))
566 vendor_dynamic_partitions_dict = common.LoadDictionaryFromFile(
567 os.path.join(vendor_target_files_dir, *dynamic_partitions_info_path))
Daniel Normana61cde02019-05-03 14:19:13 -0700568
569 merged_dynamic_partitions_dict = merge_dynamic_partition_info_dicts(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700570 framework_dict=framework_dynamic_partitions_dict,
571 vendor_dict=vendor_dynamic_partitions_dict,
Daniel Normana61cde02019-05-03 14:19:13 -0700572 # META/dynamic_partitions_info.txt does not use dynamic_partition_list.
573 include_dynamic_partition_list=False,
574 size_suffix='_size',
575 list_suffix='_partition_list')
576
577 output_dynamic_partitions_info_txt = os.path.join(
578 output_target_files_dir, 'META', 'dynamic_partitions_info.txt')
Chris Grossfabf50a2019-05-02 12:42:09 -0700579 write_sorted_data(
580 data=merged_dynamic_partitions_dict,
581 path=output_dynamic_partitions_info_txt)
582
583
Daniel Normand5d70ea2019-06-05 15:13:43 -0700584def process_apex_keys_apk_certs_common(framework_target_files_dir,
585 vendor_target_files_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700586 output_target_files_dir, file_name):
Tao Bao2ad4b822019-06-27 16:52:12 -0700587 """Performs special processing for META/apexkeys.txt or META/apkcerts.txt.
Chris Grossfabf50a2019-05-02 12:42:09 -0700588
589 This function merges the contents of the META/apexkeys.txt or
Tao Bao2ad4b822019-06-27 16:52:12 -0700590 META/apkcerts.txt files from the framework directory and the vendor directory,
591 placing the merged result in the output directory. The precondition in that
592 the files are already extracted. The post condition is that the output
593 META/apexkeys.txt or META/apkcerts.txt contains the merged content.
Chris Grossfabf50a2019-05-02 12:42:09 -0700594
595 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700596 framework_target_files_dir: The name of a directory containing the special
597 items extracted from the framework target files package.
598 vendor_target_files_dir: The name of a directory containing the special
599 items extracted from the vendor target files package.
Chris Grossfabf50a2019-05-02 12:42:09 -0700600 output_target_files_dir: The name of a directory that will be used to create
601 the output target files package after all the special cases are processed.
602 file_name: The name of the file to merge. One of apkcerts.txt or
603 apexkeys.txt.
604 """
605
606 def read_helper(d):
607 temp = {}
608 file_path = os.path.join(d, 'META', file_name)
609 with open(file_path) as f:
610 for line in f:
611 if line.strip():
612 temp[line.split()[0]] = line.strip()
613 return temp
614
Daniel Normand5d70ea2019-06-05 15:13:43 -0700615 framework_dict = read_helper(framework_target_files_dir)
616 vendor_dict = read_helper(vendor_target_files_dir)
Chris Grossfabf50a2019-05-02 12:42:09 -0700617
Daniel Normand5d70ea2019-06-05 15:13:43 -0700618 for key in framework_dict:
619 if key in vendor_dict and vendor_dict[key] != framework_dict[key]:
Chris Grossfabf50a2019-05-02 12:42:09 -0700620 raise ValueError('Conflicting entries found in %s:\n %s and\n %s' %
Daniel Normand5d70ea2019-06-05 15:13:43 -0700621 (file_name, framework_dict[key], vendor_dict[key]))
622 vendor_dict[key] = framework_dict[key]
Chris Grossfabf50a2019-05-02 12:42:09 -0700623
624 output_file = os.path.join(output_target_files_dir, 'META', file_name)
625
Daniel Normand5d70ea2019-06-05 15:13:43 -0700626 write_sorted_data(data=vendor_dict.values(), path=output_file)
Daniel Normana61cde02019-05-03 14:19:13 -0700627
628
Daniel Normand5d70ea2019-06-05 15:13:43 -0700629def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
Daniel Norman72c626f2019-05-13 15:58:14 -0700630 output_target_files_dir):
631 """Creates named copies of each build's file_contexts.bin in output META/."""
Daniel Normand5d70ea2019-06-05 15:13:43 -0700632 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
633 'framework_file_contexts.bin')
634 if not os.path.exists(framework_fc_path):
635 framework_fc_path = os.path.join(framework_target_files_dir, 'META',
636 'file_contexts.bin')
637 if not os.path.exists(framework_fc_path):
638 raise ValueError('Missing framework file_contexts.bin.')
639 shutil.copyfile(
640 framework_fc_path,
641 os.path.join(output_target_files_dir, 'META',
642 'framework_file_contexts.bin'))
643
644 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
645 'vendor_file_contexts.bin')
646 if not os.path.exists(vendor_fc_path):
647 vendor_fc_path = os.path.join(vendor_target_files_dir, 'META',
Daniel Normanedf12472019-05-22 10:47:08 -0700648 'file_contexts.bin')
Daniel Normand5d70ea2019-06-05 15:13:43 -0700649 if not os.path.exists(vendor_fc_path):
650 raise ValueError('Missing vendor file_contexts.bin.')
Daniel Norman72c626f2019-05-13 15:58:14 -0700651 shutil.copyfile(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700652 vendor_fc_path,
653 os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
Daniel Norman72c626f2019-05-13 15:58:14 -0700654
655
Daniel Normand5d70ea2019-06-05 15:13:43 -0700656def process_special_cases(framework_target_files_temp_dir,
657 vendor_target_files_temp_dir,
658 output_target_files_temp_dir,
659 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700660 """Performs special-case processing for certain target files items.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800661
662 Certain files in the output target files package require special-case
663 processing. This function performs all that special-case processing.
664
665 Args:
Daniel Normand5d70ea2019-06-05 15:13:43 -0700666 framework_target_files_temp_dir: The name of a directory containing the
667 special items extracted from the framework target files package.
668 vendor_target_files_temp_dir: The name of a directory containing the special
669 items extracted from the vendor target files package.
Daniel Normane5b134a2019-04-17 14:54:06 -0700670 output_target_files_temp_dir: The name of a directory that will be used to
671 create the output target files package after all the special cases are
672 processed.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700673 framework_misc_info_keys: A list of keys to obtain from the framework
674 instance of META/misc_info.txt. The remaining keys from the vendor
675 instance.
Bill Peckham364c1cc2019-03-29 18:27:23 -0700676 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700677 devices and write it to the system image.
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
686 if rebuild_recovery:
687 append_recovery_to_filesystem_config(
688 output_target_files_temp_dir=output_target_files_temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800689
Daniel Norman72c626f2019-05-13 15:58:14 -0700690 copy_file_contexts(
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,
Daniel Norman72c626f2019-05-13 15:58:14 -0700693 output_target_files_dir=output_target_files_temp_dir)
694
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800695 process_misc_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700696 framework_target_files_temp_dir=framework_target_files_temp_dir,
697 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800698 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700699 framework_misc_info_keys=framework_misc_info_keys)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800700
Daniel Normana61cde02019-05-03 14:19:13 -0700701 process_dynamic_partitions_info_txt(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700702 framework_target_files_dir=framework_target_files_temp_dir,
703 vendor_target_files_dir=vendor_target_files_temp_dir,
Daniel Norman714bd122019-05-08 16:20:02 -0700704 output_target_files_dir=output_target_files_temp_dir)
Daniel Normana61cde02019-05-03 14:19:13 -0700705
Chris Grossfabf50a2019-05-02 12:42:09 -0700706 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700707 framework_target_files_dir=framework_target_files_temp_dir,
708 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700709 output_target_files_dir=output_target_files_temp_dir,
710 file_name='apkcerts.txt')
711
712 process_apex_keys_apk_certs_common(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700713 framework_target_files_dir=framework_target_files_temp_dir,
714 vendor_target_files_dir=vendor_target_files_temp_dir,
Chris Grossfabf50a2019-05-02 12:42:09 -0700715 output_target_files_dir=output_target_files_temp_dir,
716 file_name='apexkeys.txt')
717
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800718
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900719def files_from_path(target_path, extra_args=None):
Tao Bao2ad4b822019-06-27 16:52:12 -0700720 """Gets files under given path.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800721
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900722 Get (sub)files from given target path and return sorted list.
723
724 Args:
725 target_path: Target path to get subfiles.
726 extra_args: List of extra argument for find command. Optional.
727
728 Returns:
729 Sorted files and directories list.
730 """
731
732 find_command = ['find', target_path] + (extra_args or [])
733 find_process = common.Run(find_command, stdout=subprocess.PIPE, verbose=False)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700734 return common.RunAndCheckOutput(['sort'],
735 stdin=find_process.stdout,
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900736 verbose=False)
737
738
739def create_merged_package(temp_dir, framework_target_files, framework_item_list,
740 vendor_target_files, vendor_item_list,
Daniel Norman4cc9df62019-07-18 10:11:07 -0700741 framework_misc_info_keys, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700742 """Merges two target files packages into one target files structure.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800743
744 Args:
745 temp_dir: The name of a directory we use when we extract items from the
Daniel Normane5b134a2019-04-17 14:54:06 -0700746 input target files packages, and also a scratch directory that we use for
747 temporary files.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700748 framework_target_files: The name of the zip archive containing the framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700749 partial target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700750 framework_item_list: The list of items to extract from the partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700751 target files package as is, meaning these items will land in the output
Daniel Normand5d70ea2019-06-05 15:13:43 -0700752 target files package exactly as they appear in the input partial framework
Daniel Normane5b134a2019-04-17 14:54:06 -0700753 target files package.
Daniel Normand5d70ea2019-06-05 15:13:43 -0700754 vendor_target_files: The name of the zip archive containing the vendor
755 partial target files package.
756 vendor_item_list: The list of items to extract from the partial vendor
757 target files package as is, meaning these items will land in the output
758 target files package exactly as they appear in the input partial vendor
Daniel Normane5b134a2019-04-17 14:54:06 -0700759 target files package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900760 framework_misc_info_keys: The list of keys to obtain from the framework
761 instance of META/misc_info.txt. The remaining keys from the vendor
762 instance.
Daniel Normana4911da2019-03-15 14:36:21 -0700763 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
Daniel Normane5b134a2019-04-17 14:54:06 -0700764 devices and write it to the system image.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800765
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900766 Returns:
767 Path to merged package under temp directory.
768 """
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800769
Daniel Normand5d70ea2019-06-05 15:13:43 -0700770 # Create directory names that we'll use when we extract files from framework,
771 # and vendor, and for zipping the final output.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800772
Daniel Normand5d70ea2019-06-05 15:13:43 -0700773 framework_target_files_temp_dir = os.path.join(temp_dir, 'framework')
774 vendor_target_files_temp_dir = os.path.join(temp_dir, 'vendor')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800775 output_target_files_temp_dir = os.path.join(temp_dir, 'output')
776
Daniel Normand5d70ea2019-06-05 15:13:43 -0700777 # Extract "as is" items from the input framework partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800778 # We extract them directly into the output temporary directory since the
779 # items do not need special case processing.
780
Bill Peckham889b0c62019-02-21 18:53:37 -0800781 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700782 target_files=framework_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800783 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700784 extract_item_list=framework_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800785
Daniel Normand5d70ea2019-06-05 15:13:43 -0700786 # Extract "as is" items from the input vendor partial target files package. We
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800787 # extract them directly into the output temporary directory since the items
788 # do not need special case processing.
789
Bill Peckham889b0c62019-02-21 18:53:37 -0800790 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700791 target_files=vendor_target_files,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800792 target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700793 extract_item_list=vendor_item_list)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800794
Daniel Normand5d70ea2019-06-05 15:13:43 -0700795 # Extract "special" items from the input framework partial target files
796 # package. We extract these items to different directory since they require
797 # special processing before they will end up in the output directory.
798
799 extract_items(
800 target_files=framework_target_files,
801 target_files_temp_dir=framework_target_files_temp_dir,
802 extract_item_list=FRAMEWORK_EXTRACT_SPECIAL_ITEM_LIST)
803
804 # Extract "special" items from the input vendor partial target files package.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800805 # We extract these items to different directory since they require special
806 # processing before they will end up in the output directory.
807
Bill Peckham889b0c62019-02-21 18:53:37 -0800808 extract_items(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700809 target_files=vendor_target_files,
810 target_files_temp_dir=vendor_target_files_temp_dir,
811 extract_item_list=VENDOR_EXTRACT_SPECIAL_ITEM_LIST)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800812
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800813 # Now that the temporary directories contain all the extracted files, perform
814 # special case processing on any items that need it. After this function
815 # completes successfully, all the files we need to create the output target
816 # files package are in place.
817
Bill Peckham889b0c62019-02-21 18:53:37 -0800818 process_special_cases(
Daniel Normand5d70ea2019-06-05 15:13:43 -0700819 framework_target_files_temp_dir=framework_target_files_temp_dir,
820 vendor_target_files_temp_dir=vendor_target_files_temp_dir,
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800821 output_target_files_temp_dir=output_target_files_temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -0700822 framework_misc_info_keys=framework_misc_info_keys,
Bill Peckham364c1cc2019-03-29 18:27:23 -0700823 rebuild_recovery=rebuild_recovery)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800824
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900825 return output_target_files_temp_dir
826
827
828def generate_images(target_files_dir, rebuild_recovery):
829 """Generate images from target files.
830
831 This function takes merged output temporary directory and create images
832 from it.
833
834 Args:
835 target_files_dir: Path to merged temp directory.
836 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
837 devices and write it to the system image.
838 """
839
840 # Regenerate IMAGES in the target directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800841
Daniel Normana4911da2019-03-15 14:36:21 -0700842 add_img_args = ['--verbose']
843 if rebuild_recovery:
844 add_img_args.append('--rebuild_recovery')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900845 add_img_args.append(target_files_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800846
847 add_img_to_target_files.main(add_img_args)
848
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900849
850def generate_super_empty_image(target_dir, output_super_empty):
Tao Bao2ad4b822019-06-27 16:52:12 -0700851 """Generates super_empty image from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900852
853 Args:
854 target_dir: Path to the target file package which contains misc_info.txt for
855 detailed information for super image.
856 output_super_empty: If provided, copies a super_empty.img file from the
857 target files package to this path.
858 """
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700859 # Create super_empty.img using the merged misc_info.txt.
860
Daniel Norman4cc9df62019-07-18 10:11:07 -0700861 misc_info_txt = os.path.join(target_dir, 'META', 'misc_info.txt')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700862
Kiyoung Kimebe7c9c2019-06-25 17:09:55 +0900863 use_dynamic_partitions = common.LoadDictionaryFromFile(misc_info_txt).get(
864 'use_dynamic_partitions')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700865
866 if use_dynamic_partitions != 'true' and output_super_empty:
867 raise ValueError(
868 'Building super_empty.img requires use_dynamic_partitions=true.')
869 elif use_dynamic_partitions == 'true':
Daniel Norman4cc9df62019-07-18 10:11:07 -0700870 super_empty_img = os.path.join(target_dir, 'IMAGES', 'super_empty.img')
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700871 build_super_image_args = [
872 misc_info_txt,
873 super_empty_img,
874 ]
875 build_super_image.main(build_super_image_args)
876
877 # Copy super_empty.img to the user-provided output_super_empty location.
878 if output_super_empty:
879 shutil.copyfile(super_empty_img, output_super_empty)
880
Daniel Normanb8a2f9d2019-04-24 12:55:51 -0700881
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900882def create_target_files_archive(output_file, source_dir, temp_dir):
Tao Bao2ad4b822019-06-27 16:52:12 -0700883 """Creates archive from target package.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900884
885 Args:
886 output_file: The name of the zip archive target files package.
887 source_dir: The target directory contains package to be archived.
888 temp_dir: Path to temporary directory for any intermediate files.
889 """
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800890 output_target_files_list = os.path.join(temp_dir, 'output.list')
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900891 output_zip = os.path.abspath(output_file)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700892 output_target_files_meta_dir = os.path.join(source_dir, 'META')
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800893
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900894 meta_content = files_from_path(output_target_files_meta_dir)
Daniel Norman4cc9df62019-07-18 10:11:07 -0700895 other_content = files_from_path(
896 source_dir,
897 ['-path', output_target_files_meta_dir, '-prune', '-o', '-print'])
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800898
Tao Bao2ad4b822019-06-27 16:52:12 -0700899 with open(output_target_files_list, 'w') as f:
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800900 f.write(meta_content)
901 f.write(other_content)
902
903 command = [
Bill Peckhamf753e152019-02-19 18:02:46 -0800904 'soong_zip',
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800905 '-d',
Daniel Normane5b134a2019-04-17 14:54:06 -0700906 '-o',
907 output_zip,
908 '-C',
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900909 source_dir,
Daniel Normane5b134a2019-04-17 14:54:06 -0700910 '-l',
911 output_target_files_list,
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800912 ]
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900913
914 logger.info('creating %s', output_file)
Bill Peckham889b0c62019-02-21 18:53:37 -0800915 common.RunAndWait(command, verbose=True)
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900916 logger.info('finished creating %s', output_file)
917
918 return output_zip
919
920
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900921def merge_target_files(temp_dir, framework_target_files, framework_item_list,
922 framework_misc_info_keys, vendor_target_files,
923 vendor_item_list, output_target_files, output_dir,
924 output_item_list, output_ota, output_img,
925 output_super_empty, rebuild_recovery):
Tao Bao2ad4b822019-06-27 16:52:12 -0700926 """Merges two target files packages together.
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900927
928 This function takes framework and vendor target files packages as input,
929 performs various file extractions, special case processing, and finally
930 creates a merged zip archive as output.
931
932 Args:
933 temp_dir: The name of a directory we use when we extract items from the
934 input target files packages, and also a scratch directory that we use for
935 temporary files.
936 framework_target_files: The name of the zip archive containing the framework
937 partial target files package.
938 framework_item_list: The list of items to extract from the partial framework
939 target files package as is, meaning these items will land in the output
940 target files package exactly as they appear in the input partial framework
941 target files package.
942 framework_misc_info_keys: The list of keys to obtain from the framework
943 instance of META/misc_info.txt. The remaining keys from the vendor
944 instance.
945 vendor_target_files: The name of the zip archive containing the vendor
946 partial target files package.
947 vendor_item_list: The list of items to extract from the partial vendor
948 target files package as is, meaning these items will land in the output
949 target files package exactly as they appear in the input partial vendor
950 target files package.
951 output_target_files: The name of the output zip archive target files package
952 created by merging framework and vendor.
953 output_dir: The destination directory for saving merged files.
954 output_item_list: The list of items to copy into the output_dir.
955 output_ota: The name of the output zip archive ota package.
956 output_img: The name of the output zip archive img package.
957 output_super_empty: If provided, creates a super_empty.img file from the
958 merged target files package and saves it at this path.
959 rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
960 devices and write it to the system image.
961 """
962
963 logger.info('starting: merge framework %s and vendor %s into output %s',
964 framework_target_files, vendor_target_files, output_target_files)
965
966 output_target_files_temp_dir = create_merged_package(
967 temp_dir, framework_target_files, framework_item_list,
968 vendor_target_files, vendor_item_list, framework_misc_info_keys,
969 rebuild_recovery)
970
971 generate_images(output_target_files_temp_dir, rebuild_recovery)
972
973 generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
974
975 if output_img:
976 # Create the IMG package from the merged target files (before zipping, in
977 # order to avoid an unnecessary unzip and copy).
Daniel Norman4cc9df62019-07-18 10:11:07 -0700978 img_from_target_files.main([output_target_files_temp_dir, output_img])
Kiyoung Kim7cbeda72019-06-28 13:26:04 +0900979
980 # Finally, create the output target files zip archive and/or copy the
981 # output items to the output target files directory.
982
983 if output_dir:
984 copy_items(output_target_files_temp_dir, output_dir, output_item_list)
985
986 if not output_target_files:
987 return
988
989 output_zip = create_target_files_archive(output_target_files,
990 output_target_files_temp_dir,
991 temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -0800992
Daniel Norman3b64ce12019-04-16 16:11:35 -0700993 # Create the OTA package from the merged target files package.
994
995 if output_ota:
Daniel Norman4cc9df62019-07-18 10:11:07 -0700996 ota_from_target_files.main([output_zip, output_ota])
Daniel Norman3b64ce12019-04-16 16:11:35 -0700997
Daniel Norman1bd2a1d2019-04-18 12:32:18 -0700998
Daniel Norman2c99c5b2019-03-07 13:01:48 -0800999def call_func_with_temp_dir(func, keep_tmp):
Tao Bao2ad4b822019-06-27 16:52:12 -07001000 """Manages the creation and cleanup of the temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001001
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001002 This function calls the given function after first creating a temporary
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001003 directory. It also cleans up the temporary directory.
1004
1005 Args:
Daniel Normane5b134a2019-04-17 14:54:06 -07001006 func: The function to call. Should accept one parameter, the path to the
1007 temporary directory.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001008 keep_tmp: Keep the temporary directory after processing is complete.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001009 """
1010
1011 # Create a temporary directory. This will serve as the parent of directories
1012 # we use when we extract items from the input target files packages, and also
1013 # a scratch directory that we use for temporary files.
1014
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001015 temp_dir = common.MakeTempDir(prefix='merge_target_files_')
1016
1017 try:
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001018 func(temp_dir)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001019 finally:
1020 if keep_tmp:
1021 logger.info('keeping %s', temp_dir)
1022 else:
1023 common.Cleanup()
1024
1025
1026def main():
1027 """The main function.
1028
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001029 Process command line arguments, then call merge_target_files to
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001030 perform the heavy lifting.
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001031 """
1032
1033 common.InitLogging()
1034
Bill Peckhamf753e152019-02-19 18:02:46 -08001035 def option_handler(o, a):
1036 if o == '--system-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001037 logger.warning(
1038 '--system-target-files has been renamed to --framework-target-files')
1039 OPTIONS.framework_target_files = a
1040 elif o == '--framework-target-files':
1041 OPTIONS.framework_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001042 elif o == '--system-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001043 logger.warning(
1044 '--system-item-list has been renamed to --framework-item-list')
1045 OPTIONS.framework_item_list = a
1046 elif o == '--framework-item-list':
1047 OPTIONS.framework_item_list = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001048 elif o == '--system-misc-info-keys':
Daniel Norman4cc9df62019-07-18 10:11:07 -07001049 logger.warning('--system-misc-info-keys has been renamed to '
1050 '--framework-misc-info-keys')
Daniel Normand5d70ea2019-06-05 15:13:43 -07001051 OPTIONS.framework_misc_info_keys = a
1052 elif o == '--framework-misc-info-keys':
1053 OPTIONS.framework_misc_info_keys = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001054 elif o == '--other-target-files':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001055 logger.warning(
1056 '--other-target-files has been renamed to --vendor-target-files')
1057 OPTIONS.vendor_target_files = a
1058 elif o == '--vendor-target-files':
1059 OPTIONS.vendor_target_files = a
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001060 elif o == '--other-item-list':
Daniel Normand5d70ea2019-06-05 15:13:43 -07001061 logger.warning('--other-item-list has been renamed to --vendor-item-list')
1062 OPTIONS.vendor_item_list = a
1063 elif o == '--vendor-item-list':
1064 OPTIONS.vendor_item_list = a
Bill Peckhamf753e152019-02-19 18:02:46 -08001065 elif o == '--output-target-files':
1066 OPTIONS.output_target_files = a
Daniel Normanfdb38812019-04-15 09:47:24 -07001067 elif o == '--output-dir':
1068 OPTIONS.output_dir = a
1069 elif o == '--output-item-list':
1070 OPTIONS.output_item_list = a
Daniel Norman3b64ce12019-04-16 16:11:35 -07001071 elif o == '--output-ota':
1072 OPTIONS.output_ota = a
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001073 elif o == '--output-img':
1074 OPTIONS.output_img = a
Daniel Normanf0318252019-04-15 11:34:56 -07001075 elif o == '--output-super-empty':
1076 OPTIONS.output_super_empty = a
Daniel Normana4911da2019-03-15 14:36:21 -07001077 elif o == '--rebuild_recovery':
1078 OPTIONS.rebuild_recovery = True
Bill Peckham364c1cc2019-03-29 18:27:23 -07001079 elif o == '--keep-tmp':
Bill Peckhamf753e152019-02-19 18:02:46 -08001080 OPTIONS.keep_tmp = True
1081 else:
1082 return False
1083 return True
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001084
Bill Peckhamf753e152019-02-19 18:02:46 -08001085 args = common.ParseOptions(
Daniel Normane5b134a2019-04-17 14:54:06 -07001086 sys.argv[1:],
1087 __doc__,
Bill Peckhamf753e152019-02-19 18:02:46 -08001088 extra_long_opts=[
1089 'system-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001090 'framework-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001091 'system-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001092 'framework-item-list=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001093 'system-misc-info-keys=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001094 'framework-misc-info-keys=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001095 'other-target-files=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001096 'vendor-target-files=',
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001097 'other-item-list=',
Daniel Normand5d70ea2019-06-05 15:13:43 -07001098 'vendor-item-list=',
Bill Peckhamf753e152019-02-19 18:02:46 -08001099 'output-target-files=',
Daniel Normanfdb38812019-04-15 09:47:24 -07001100 'output-dir=',
1101 'output-item-list=',
Daniel Norman3b64ce12019-04-16 16:11:35 -07001102 'output-ota=',
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001103 'output-img=',
Daniel Normanf0318252019-04-15 11:34:56 -07001104 'output-super-empty=',
Daniel Normana4911da2019-03-15 14:36:21 -07001105 'rebuild_recovery',
Bill Peckham364c1cc2019-03-29 18:27:23 -07001106 'keep-tmp',
Bill Peckhamf753e152019-02-19 18:02:46 -08001107 ],
1108 extra_option_handler=option_handler)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001109
Tao Bao2ad4b822019-06-27 16:52:12 -07001110 # pylint: disable=too-many-boolean-expressions
Daniel Normand5d70ea2019-06-05 15:13:43 -07001111 if (args or OPTIONS.framework_target_files is None or
1112 OPTIONS.vendor_target_files is None or
Daniel Normane5b134a2019-04-17 14:54:06 -07001113 (OPTIONS.output_target_files is None and OPTIONS.output_dir is None) or
1114 (OPTIONS.output_dir is not None and OPTIONS.output_item_list is None)):
Bill Peckhamf753e152019-02-19 18:02:46 -08001115 common.Usage(__doc__)
Bill Peckham889b0c62019-02-21 18:53:37 -08001116 sys.exit(1)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001117
Daniel Normand5d70ea2019-06-05 15:13:43 -07001118 if OPTIONS.framework_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001119 framework_item_list = common.LoadListFromFile(OPTIONS.framework_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001120 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001121 framework_item_list = DEFAULT_FRAMEWORK_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001122
Daniel Normand5d70ea2019-06-05 15:13:43 -07001123 if OPTIONS.framework_misc_info_keys:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001124 framework_misc_info_keys = common.LoadListFromFile(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001125 OPTIONS.framework_misc_info_keys)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001126 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001127 framework_misc_info_keys = DEFAULT_FRAMEWORK_MISC_INFO_KEYS
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001128
Daniel Normand5d70ea2019-06-05 15:13:43 -07001129 if OPTIONS.vendor_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001130 vendor_item_list = common.LoadListFromFile(OPTIONS.vendor_item_list)
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001131 else:
Daniel Normand5d70ea2019-06-05 15:13:43 -07001132 vendor_item_list = DEFAULT_VENDOR_ITEM_LIST
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001133
Daniel Normanfdb38812019-04-15 09:47:24 -07001134 if OPTIONS.output_item_list:
Daniel Norman4cc9df62019-07-18 10:11:07 -07001135 output_item_list = common.LoadListFromFile(OPTIONS.output_item_list)
Daniel Normanfdb38812019-04-15 09:47:24 -07001136 else:
1137 output_item_list = None
1138
Daniel Normane5964522019-03-19 10:32:03 -07001139 if not validate_config_lists(
Daniel Normand5d70ea2019-06-05 15:13:43 -07001140 framework_item_list=framework_item_list,
1141 framework_misc_info_keys=framework_misc_info_keys,
1142 vendor_item_list=vendor_item_list):
Daniel Normane5964522019-03-19 10:32:03 -07001143 sys.exit(1)
1144
Daniel Norman2c99c5b2019-03-07 13:01:48 -08001145 call_func_with_temp_dir(
1146 lambda temp_dir: merge_target_files(
1147 temp_dir=temp_dir,
Daniel Normand5d70ea2019-06-05 15:13:43 -07001148 framework_target_files=OPTIONS.framework_target_files,
1149 framework_item_list=framework_item_list,
1150 framework_misc_info_keys=framework_misc_info_keys,
1151 vendor_target_files=OPTIONS.vendor_target_files,
1152 vendor_item_list=vendor_item_list,
Daniel Normana4911da2019-03-15 14:36:21 -07001153 output_target_files=OPTIONS.output_target_files,
Daniel Normanfdb38812019-04-15 09:47:24 -07001154 output_dir=OPTIONS.output_dir,
1155 output_item_list=output_item_list,
Daniel Norman3b64ce12019-04-16 16:11:35 -07001156 output_ota=OPTIONS.output_ota,
Daniel Norman1bd2a1d2019-04-18 12:32:18 -07001157 output_img=OPTIONS.output_img,
Daniel Normanf0318252019-04-15 11:34:56 -07001158 output_super_empty=OPTIONS.output_super_empty,
Daniel Normane5b134a2019-04-17 14:54:06 -07001159 rebuild_recovery=OPTIONS.rebuild_recovery), OPTIONS.keep_tmp)
Bill Peckhame9eb5f92019-02-01 15:52:10 -08001160
1161
1162if __name__ == '__main__':
Bill Peckham889b0c62019-02-21 18:53:37 -08001163 main()