xref: /aosp_15_r20/build/make/tools/releasetools/merge/merge_utils.py (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
1*9e94795aSAndroid Build Coastguard Worker#!/usr/bin/env python
2*9e94795aSAndroid Build Coastguard Worker#
3*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project
4*9e94795aSAndroid Build Coastguard Worker#
5*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6*9e94795aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
7*9e94795aSAndroid Build Coastguard Worker# the License at
8*9e94795aSAndroid Build Coastguard Worker#
9*9e94795aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
10*9e94795aSAndroid Build Coastguard Worker#
11*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13*9e94795aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14*9e94795aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
15*9e94795aSAndroid Build Coastguard Worker# the License.
16*9e94795aSAndroid Build Coastguard Worker#
17*9e94795aSAndroid Build Coastguard Worker"""Common utility functions shared by merge_* scripts.
18*9e94795aSAndroid Build Coastguard Worker
19*9e94795aSAndroid Build Coastguard WorkerExpects items in OPTIONS prepared by merge_target_files.py.
20*9e94795aSAndroid Build Coastguard Worker"""
21*9e94795aSAndroid Build Coastguard Worker
22*9e94795aSAndroid Build Coastguard Workerimport fnmatch
23*9e94795aSAndroid Build Coastguard Workerimport logging
24*9e94795aSAndroid Build Coastguard Workerimport os
25*9e94795aSAndroid Build Coastguard Workerimport re
26*9e94795aSAndroid Build Coastguard Workerimport shutil
27*9e94795aSAndroid Build Coastguard Workerimport zipfile
28*9e94795aSAndroid Build Coastguard Worker
29*9e94795aSAndroid Build Coastguard Workerimport common
30*9e94795aSAndroid Build Coastguard Worker
31*9e94795aSAndroid Build Coastguard Workerlogger = logging.getLogger(__name__)
32*9e94795aSAndroid Build Coastguard WorkerOPTIONS = common.OPTIONS
33*9e94795aSAndroid Build Coastguard Worker
34*9e94795aSAndroid Build Coastguard Worker
35*9e94795aSAndroid Build Coastguard Workerdef ExtractItems(input_zip, output_dir, extract_item_list):
36*9e94795aSAndroid Build Coastguard Worker  """Extracts items in extract_item_list from a zip to a dir."""
37*9e94795aSAndroid Build Coastguard Worker
38*9e94795aSAndroid Build Coastguard Worker  # Filter the extract_item_list to remove any items that do not exist in the
39*9e94795aSAndroid Build Coastguard Worker  # zip file. Otherwise, the extraction step will fail.
40*9e94795aSAndroid Build Coastguard Worker
41*9e94795aSAndroid Build Coastguard Worker  with zipfile.ZipFile(input_zip, allowZip64=True) as input_zipfile:
42*9e94795aSAndroid Build Coastguard Worker    input_namelist = input_zipfile.namelist()
43*9e94795aSAndroid Build Coastguard Worker
44*9e94795aSAndroid Build Coastguard Worker  filtered_extract_item_list = []
45*9e94795aSAndroid Build Coastguard Worker  for pattern in extract_item_list:
46*9e94795aSAndroid Build Coastguard Worker    if fnmatch.filter(input_namelist, pattern):
47*9e94795aSAndroid Build Coastguard Worker      filtered_extract_item_list.append(pattern)
48*9e94795aSAndroid Build Coastguard Worker
49*9e94795aSAndroid Build Coastguard Worker  common.UnzipToDir(input_zip, output_dir, filtered_extract_item_list)
50*9e94795aSAndroid Build Coastguard Worker
51*9e94795aSAndroid Build Coastguard Worker
52*9e94795aSAndroid Build Coastguard Workerdef CopyItems(from_dir, to_dir, copy_item_list):
53*9e94795aSAndroid Build Coastguard Worker  """Copies the items in copy_item_list from source to destination directory.
54*9e94795aSAndroid Build Coastguard Worker
55*9e94795aSAndroid Build Coastguard Worker  copy_item_list may include files and directories. Will copy the matched
56*9e94795aSAndroid Build Coastguard Worker  files and create the matched directories.
57*9e94795aSAndroid Build Coastguard Worker
58*9e94795aSAndroid Build Coastguard Worker  Args:
59*9e94795aSAndroid Build Coastguard Worker    from_dir: The source directory.
60*9e94795aSAndroid Build Coastguard Worker    to_dir: The destination directory.
61*9e94795aSAndroid Build Coastguard Worker    copy_item_list: Items to be copied.
62*9e94795aSAndroid Build Coastguard Worker  """
63*9e94795aSAndroid Build Coastguard Worker  item_paths = []
64*9e94795aSAndroid Build Coastguard Worker  for root, dirs, files in os.walk(from_dir):
65*9e94795aSAndroid Build Coastguard Worker    item_paths.extend(
66*9e94795aSAndroid Build Coastguard Worker        os.path.relpath(path=os.path.join(root, item_name), start=from_dir)
67*9e94795aSAndroid Build Coastguard Worker        for item_name in files + dirs)
68*9e94795aSAndroid Build Coastguard Worker
69*9e94795aSAndroid Build Coastguard Worker  filtered = set()
70*9e94795aSAndroid Build Coastguard Worker  for pattern in copy_item_list:
71*9e94795aSAndroid Build Coastguard Worker    filtered.update(fnmatch.filter(item_paths, pattern))
72*9e94795aSAndroid Build Coastguard Worker
73*9e94795aSAndroid Build Coastguard Worker  for item in filtered:
74*9e94795aSAndroid Build Coastguard Worker    original_path = os.path.join(from_dir, item)
75*9e94795aSAndroid Build Coastguard Worker    copied_path = os.path.join(to_dir, item)
76*9e94795aSAndroid Build Coastguard Worker    copied_parent_path = os.path.dirname(copied_path)
77*9e94795aSAndroid Build Coastguard Worker    if not os.path.exists(copied_parent_path):
78*9e94795aSAndroid Build Coastguard Worker      os.makedirs(copied_parent_path)
79*9e94795aSAndroid Build Coastguard Worker    if os.path.islink(original_path):
80*9e94795aSAndroid Build Coastguard Worker      os.symlink(os.readlink(original_path), copied_path)
81*9e94795aSAndroid Build Coastguard Worker    elif os.path.isdir(original_path):
82*9e94795aSAndroid Build Coastguard Worker      if not os.path.exists(copied_path):
83*9e94795aSAndroid Build Coastguard Worker        os.makedirs(copied_path)
84*9e94795aSAndroid Build Coastguard Worker    else:
85*9e94795aSAndroid Build Coastguard Worker      shutil.copyfile(original_path, copied_path)
86*9e94795aSAndroid Build Coastguard Worker
87*9e94795aSAndroid Build Coastguard Worker
88*9e94795aSAndroid Build Coastguard Workerdef GetTargetFilesItems(target_files_zipfile_or_dir):
89*9e94795aSAndroid Build Coastguard Worker  """Gets a list of target files items."""
90*9e94795aSAndroid Build Coastguard Worker  if zipfile.is_zipfile(target_files_zipfile_or_dir):
91*9e94795aSAndroid Build Coastguard Worker    with zipfile.ZipFile(target_files_zipfile_or_dir, allowZip64=True) as fz:
92*9e94795aSAndroid Build Coastguard Worker      return fz.namelist()
93*9e94795aSAndroid Build Coastguard Worker  elif os.path.isdir(target_files_zipfile_or_dir):
94*9e94795aSAndroid Build Coastguard Worker    item_list = []
95*9e94795aSAndroid Build Coastguard Worker    for root, dirs, files in os.walk(target_files_zipfile_or_dir):
96*9e94795aSAndroid Build Coastguard Worker      item_list.extend(
97*9e94795aSAndroid Build Coastguard Worker          os.path.relpath(path=os.path.join(root, item),
98*9e94795aSAndroid Build Coastguard Worker                          start=target_files_zipfile_or_dir)
99*9e94795aSAndroid Build Coastguard Worker          for item in dirs + files)
100*9e94795aSAndroid Build Coastguard Worker    return item_list
101*9e94795aSAndroid Build Coastguard Worker  else:
102*9e94795aSAndroid Build Coastguard Worker    raise ValueError('Target files should be either zipfile or directory.')
103*9e94795aSAndroid Build Coastguard Worker
104*9e94795aSAndroid Build Coastguard Worker
105*9e94795aSAndroid Build Coastguard Workerdef CollectTargetFiles(input_zipfile_or_dir, output_dir, item_list=None):
106*9e94795aSAndroid Build Coastguard Worker  """Extracts input zipfile or copy input directory to output directory.
107*9e94795aSAndroid Build Coastguard Worker
108*9e94795aSAndroid Build Coastguard Worker  Extracts the input zipfile if `input_zipfile_or_dir` is a zip archive, or
109*9e94795aSAndroid Build Coastguard Worker  copies the items if `input_zipfile_or_dir` is a directory.
110*9e94795aSAndroid Build Coastguard Worker
111*9e94795aSAndroid Build Coastguard Worker  Args:
112*9e94795aSAndroid Build Coastguard Worker    input_zipfile_or_dir: The input target files, could be either a zipfile to
113*9e94795aSAndroid Build Coastguard Worker      extract or a directory to copy.
114*9e94795aSAndroid Build Coastguard Worker    output_dir: The output directory that the input files are either extracted
115*9e94795aSAndroid Build Coastguard Worker      or copied.
116*9e94795aSAndroid Build Coastguard Worker    item_list: Files to be extracted or copied. Will extract or copy all files
117*9e94795aSAndroid Build Coastguard Worker      if omitted.
118*9e94795aSAndroid Build Coastguard Worker  """
119*9e94795aSAndroid Build Coastguard Worker  patterns = item_list if item_list else ('*',)
120*9e94795aSAndroid Build Coastguard Worker  if zipfile.is_zipfile(input_zipfile_or_dir):
121*9e94795aSAndroid Build Coastguard Worker    ExtractItems(input_zipfile_or_dir, output_dir, patterns)
122*9e94795aSAndroid Build Coastguard Worker  elif os.path.isdir(input_zipfile_or_dir):
123*9e94795aSAndroid Build Coastguard Worker    CopyItems(input_zipfile_or_dir, output_dir, patterns)
124*9e94795aSAndroid Build Coastguard Worker  else:
125*9e94795aSAndroid Build Coastguard Worker    raise ValueError('Target files should be either zipfile or directory.')
126*9e94795aSAndroid Build Coastguard Worker
127*9e94795aSAndroid Build Coastguard Worker
128*9e94795aSAndroid Build Coastguard Workerdef WriteSortedData(data, path):
129*9e94795aSAndroid Build Coastguard Worker  """Writes the sorted contents of either a list or dict to file.
130*9e94795aSAndroid Build Coastguard Worker
131*9e94795aSAndroid Build Coastguard Worker  This function sorts the contents of the list or dict and then writes the
132*9e94795aSAndroid Build Coastguard Worker  resulting sorted contents to a file specified by path.
133*9e94795aSAndroid Build Coastguard Worker
134*9e94795aSAndroid Build Coastguard Worker  Args:
135*9e94795aSAndroid Build Coastguard Worker    data: The list or dict to sort and write.
136*9e94795aSAndroid Build Coastguard Worker    path: Path to the file to write the sorted values to. The file at path will
137*9e94795aSAndroid Build Coastguard Worker      be overridden if it exists.
138*9e94795aSAndroid Build Coastguard Worker  """
139*9e94795aSAndroid Build Coastguard Worker  with open(path, 'w') as output:
140*9e94795aSAndroid Build Coastguard Worker    for entry in sorted(data):
141*9e94795aSAndroid Build Coastguard Worker      out_str = '{}={}\n'.format(entry, data[entry]) if isinstance(
142*9e94795aSAndroid Build Coastguard Worker          data, dict) else '{}\n'.format(entry)
143*9e94795aSAndroid Build Coastguard Worker      output.write(out_str)
144*9e94795aSAndroid Build Coastguard Worker
145*9e94795aSAndroid Build Coastguard Worker
146*9e94795aSAndroid Build Coastguard Workerdef ValidateConfigLists():
147*9e94795aSAndroid Build Coastguard Worker  """Performs validations on the merge config lists.
148*9e94795aSAndroid Build Coastguard Worker
149*9e94795aSAndroid Build Coastguard Worker  Returns:
150*9e94795aSAndroid Build Coastguard Worker    False if a validation fails, otherwise true.
151*9e94795aSAndroid Build Coastguard Worker  """
152*9e94795aSAndroid Build Coastguard Worker  has_error = False
153*9e94795aSAndroid Build Coastguard Worker
154*9e94795aSAndroid Build Coastguard Worker  # Check that partitions only come from one input.
155*9e94795aSAndroid Build Coastguard Worker  framework_partitions = ItemListToPartitionSet(OPTIONS.framework_item_list)
156*9e94795aSAndroid Build Coastguard Worker  vendor_partitions = ItemListToPartitionSet(OPTIONS.vendor_item_list)
157*9e94795aSAndroid Build Coastguard Worker  from_both = framework_partitions.intersection(vendor_partitions)
158*9e94795aSAndroid Build Coastguard Worker  if from_both:
159*9e94795aSAndroid Build Coastguard Worker    logger.error(
160*9e94795aSAndroid Build Coastguard Worker        'Cannot extract items from the same partition in both the '
161*9e94795aSAndroid Build Coastguard Worker        'framework and vendor builds. Please ensure only one merge config '
162*9e94795aSAndroid Build Coastguard Worker        'item list (or inferred list) includes each partition: %s' %
163*9e94795aSAndroid Build Coastguard Worker        ','.join(from_both))
164*9e94795aSAndroid Build Coastguard Worker    has_error = True
165*9e94795aSAndroid Build Coastguard Worker
166*9e94795aSAndroid Build Coastguard Worker  if any([
167*9e94795aSAndroid Build Coastguard Worker      key in OPTIONS.framework_misc_info_keys
168*9e94795aSAndroid Build Coastguard Worker      for key in ('dynamic_partition_list', 'super_partition_groups')
169*9e94795aSAndroid Build Coastguard Worker  ]):
170*9e94795aSAndroid Build Coastguard Worker    logger.error('Dynamic partition misc info keys should come from '
171*9e94795aSAndroid Build Coastguard Worker                 'the vendor instance of META/misc_info.txt.')
172*9e94795aSAndroid Build Coastguard Worker    has_error = True
173*9e94795aSAndroid Build Coastguard Worker
174*9e94795aSAndroid Build Coastguard Worker  return not has_error
175*9e94795aSAndroid Build Coastguard Worker
176*9e94795aSAndroid Build Coastguard Worker
177*9e94795aSAndroid Build Coastguard Worker# In an item list (framework or vendor), we may see entries that select whole
178*9e94795aSAndroid Build Coastguard Worker# partitions. Such an entry might look like this 'SYSTEM/*' (e.g., for the
179*9e94795aSAndroid Build Coastguard Worker# system partition). The following regex matches this and extracts the
180*9e94795aSAndroid Build Coastguard Worker# partition name.
181*9e94795aSAndroid Build Coastguard Worker
182*9e94795aSAndroid Build Coastguard Worker_PARTITION_ITEM_PATTERN = re.compile(r'^([A-Z_]+)/.*$')
183*9e94795aSAndroid Build Coastguard Worker_IMAGE_PARTITION_PATTERN = re.compile(r'^IMAGES/(.*)\.img$')
184*9e94795aSAndroid Build Coastguard Worker_PREBUILT_IMAGE_PARTITION_PATTERN = re.compile(r'^PREBUILT_IMAGES/(.*)\.img$')
185*9e94795aSAndroid Build Coastguard Worker
186*9e94795aSAndroid Build Coastguard Worker
187*9e94795aSAndroid Build Coastguard Workerdef ItemListToPartitionSet(item_list):
188*9e94795aSAndroid Build Coastguard Worker  """Converts a target files item list to a partition set.
189*9e94795aSAndroid Build Coastguard Worker
190*9e94795aSAndroid Build Coastguard Worker  The item list contains items that might look like 'SYSTEM/*' or 'VENDOR/*' or
191*9e94795aSAndroid Build Coastguard Worker  'OTA/android-info.txt'. Items that end in '/*' are assumed to match entire
192*9e94795aSAndroid Build Coastguard Worker  directories where 'SYSTEM' or 'VENDOR' is a directory name that identifies the
193*9e94795aSAndroid Build Coastguard Worker  contents of a partition of the same name. Other items in the list, such as the
194*9e94795aSAndroid Build Coastguard Worker  'OTA' example contain metadata. This function iterates such a list, returning
195*9e94795aSAndroid Build Coastguard Worker  a set that contains the partition entries.
196*9e94795aSAndroid Build Coastguard Worker
197*9e94795aSAndroid Build Coastguard Worker  Args:
198*9e94795aSAndroid Build Coastguard Worker    item_list: A list of items in a target files package.
199*9e94795aSAndroid Build Coastguard Worker
200*9e94795aSAndroid Build Coastguard Worker  Returns:
201*9e94795aSAndroid Build Coastguard Worker    A set of partitions extracted from the list of items.
202*9e94795aSAndroid Build Coastguard Worker  """
203*9e94795aSAndroid Build Coastguard Worker
204*9e94795aSAndroid Build Coastguard Worker  partition_set = set()
205*9e94795aSAndroid Build Coastguard Worker
206*9e94795aSAndroid Build Coastguard Worker  for item in item_list:
207*9e94795aSAndroid Build Coastguard Worker    for pattern in (_PARTITION_ITEM_PATTERN, _IMAGE_PARTITION_PATTERN, _PREBUILT_IMAGE_PARTITION_PATTERN):
208*9e94795aSAndroid Build Coastguard Worker      partition_match = pattern.search(item.strip())
209*9e94795aSAndroid Build Coastguard Worker      if partition_match:
210*9e94795aSAndroid Build Coastguard Worker        partition = partition_match.group(1).lower()
211*9e94795aSAndroid Build Coastguard Worker        # These directories in target-files are not actual partitions.
212*9e94795aSAndroid Build Coastguard Worker        if partition not in ('meta', 'images', 'prebuilt_images'):
213*9e94795aSAndroid Build Coastguard Worker          partition_set.add(partition)
214*9e94795aSAndroid Build Coastguard Worker
215*9e94795aSAndroid Build Coastguard Worker  return partition_set
216*9e94795aSAndroid Build Coastguard Worker
217*9e94795aSAndroid Build Coastguard Worker
218*9e94795aSAndroid Build Coastguard Worker# Partitions that are grabbed from the framework partial build by default.
219*9e94795aSAndroid Build Coastguard Worker_FRAMEWORK_PARTITIONS = {
220*9e94795aSAndroid Build Coastguard Worker    'system', 'product', 'system_ext', 'system_other', 'root',
221*9e94795aSAndroid Build Coastguard Worker    'vbmeta_system', 'pvmfw'
222*9e94795aSAndroid Build Coastguard Worker}
223*9e94795aSAndroid Build Coastguard Worker
224*9e94795aSAndroid Build Coastguard Worker
225*9e94795aSAndroid Build Coastguard Workerdef InferItemList(input_namelist, framework):
226*9e94795aSAndroid Build Coastguard Worker  item_set = set()
227*9e94795aSAndroid Build Coastguard Worker
228*9e94795aSAndroid Build Coastguard Worker  # Some META items are always grabbed from partial builds directly.
229*9e94795aSAndroid Build Coastguard Worker  # Others are combined in merge_meta.py.
230*9e94795aSAndroid Build Coastguard Worker  if framework:
231*9e94795aSAndroid Build Coastguard Worker    item_set.update([
232*9e94795aSAndroid Build Coastguard Worker        'META/liblz4.so',
233*9e94795aSAndroid Build Coastguard Worker        'META/postinstall_config.txt',
234*9e94795aSAndroid Build Coastguard Worker        'META/zucchini_config.txt',
235*9e94795aSAndroid Build Coastguard Worker    ])
236*9e94795aSAndroid Build Coastguard Worker  else:  # vendor
237*9e94795aSAndroid Build Coastguard Worker    item_set.update([
238*9e94795aSAndroid Build Coastguard Worker        'META/kernel_configs.txt',
239*9e94795aSAndroid Build Coastguard Worker        'META/kernel_version.txt',
240*9e94795aSAndroid Build Coastguard Worker        'META/otakeys.txt',
241*9e94795aSAndroid Build Coastguard Worker        'META/pack_radioimages.txt',
242*9e94795aSAndroid Build Coastguard Worker        'META/releasetools.py',
243*9e94795aSAndroid Build Coastguard Worker    ])
244*9e94795aSAndroid Build Coastguard Worker
245*9e94795aSAndroid Build Coastguard Worker  # Grab a set of items for the expected partitions in the partial build.
246*9e94795aSAndroid Build Coastguard Worker  seen_partitions = []
247*9e94795aSAndroid Build Coastguard Worker  for namelist in input_namelist:
248*9e94795aSAndroid Build Coastguard Worker    if namelist.endswith('/'):
249*9e94795aSAndroid Build Coastguard Worker      continue
250*9e94795aSAndroid Build Coastguard Worker
251*9e94795aSAndroid Build Coastguard Worker    partition = namelist.split('/')[0].lower()
252*9e94795aSAndroid Build Coastguard Worker
253*9e94795aSAndroid Build Coastguard Worker    # META items are grabbed above, or merged later.
254*9e94795aSAndroid Build Coastguard Worker    if partition == 'meta':
255*9e94795aSAndroid Build Coastguard Worker      continue
256*9e94795aSAndroid Build Coastguard Worker
257*9e94795aSAndroid Build Coastguard Worker    if partition in ('images', 'prebuilt_images'):
258*9e94795aSAndroid Build Coastguard Worker      image_partition, extension = os.path.splitext(os.path.basename(namelist))
259*9e94795aSAndroid Build Coastguard Worker      if image_partition == 'vbmeta':
260*9e94795aSAndroid Build Coastguard Worker        # Always regenerate vbmeta.img since it depends on hash information
261*9e94795aSAndroid Build Coastguard Worker        # from both builds.
262*9e94795aSAndroid Build Coastguard Worker        continue
263*9e94795aSAndroid Build Coastguard Worker      if extension in ('.img', '.map'):
264*9e94795aSAndroid Build Coastguard Worker        # Include image files in IMAGES/* if the partition comes from
265*9e94795aSAndroid Build Coastguard Worker        # the expected set.
266*9e94795aSAndroid Build Coastguard Worker        if (framework and image_partition in _FRAMEWORK_PARTITIONS) or (
267*9e94795aSAndroid Build Coastguard Worker            not framework and image_partition not in _FRAMEWORK_PARTITIONS):
268*9e94795aSAndroid Build Coastguard Worker          item_set.add(namelist)
269*9e94795aSAndroid Build Coastguard Worker      elif not framework:
270*9e94795aSAndroid Build Coastguard Worker        # Include all miscellaneous non-image files in IMAGES/* from
271*9e94795aSAndroid Build Coastguard Worker        # the vendor build.
272*9e94795aSAndroid Build Coastguard Worker        item_set.add(namelist)
273*9e94795aSAndroid Build Coastguard Worker      continue
274*9e94795aSAndroid Build Coastguard Worker
275*9e94795aSAndroid Build Coastguard Worker    # Skip already-visited partitions.
276*9e94795aSAndroid Build Coastguard Worker    if partition in seen_partitions:
277*9e94795aSAndroid Build Coastguard Worker      continue
278*9e94795aSAndroid Build Coastguard Worker    seen_partitions.append(partition)
279*9e94795aSAndroid Build Coastguard Worker
280*9e94795aSAndroid Build Coastguard Worker    if (framework and partition in _FRAMEWORK_PARTITIONS) or (
281*9e94795aSAndroid Build Coastguard Worker        not framework and partition not in _FRAMEWORK_PARTITIONS):
282*9e94795aSAndroid Build Coastguard Worker      fs_config_prefix = '' if partition == 'system' else '%s_' % partition
283*9e94795aSAndroid Build Coastguard Worker      item_set.update([
284*9e94795aSAndroid Build Coastguard Worker          '%s/*' % partition.upper(),
285*9e94795aSAndroid Build Coastguard Worker          'META/%sfilesystem_config.txt' % fs_config_prefix,
286*9e94795aSAndroid Build Coastguard Worker      ])
287*9e94795aSAndroid Build Coastguard Worker
288*9e94795aSAndroid Build Coastguard Worker  return sorted(item_set)
289*9e94795aSAndroid Build Coastguard Worker
290*9e94795aSAndroid Build Coastguard Worker
291*9e94795aSAndroid Build Coastguard Workerdef InferFrameworkMiscInfoKeys(input_namelist):
292*9e94795aSAndroid Build Coastguard Worker  keys = [
293*9e94795aSAndroid Build Coastguard Worker      'ab_update',
294*9e94795aSAndroid Build Coastguard Worker      'avb_vbmeta_system',
295*9e94795aSAndroid Build Coastguard Worker      'avb_vbmeta_system_algorithm',
296*9e94795aSAndroid Build Coastguard Worker      'avb_vbmeta_system_key_path',
297*9e94795aSAndroid Build Coastguard Worker      'avb_vbmeta_system_rollback_index_location',
298*9e94795aSAndroid Build Coastguard Worker      'default_system_dev_certificate',
299*9e94795aSAndroid Build Coastguard Worker  ]
300*9e94795aSAndroid Build Coastguard Worker
301*9e94795aSAndroid Build Coastguard Worker  for partition in _FRAMEWORK_PARTITIONS:
302*9e94795aSAndroid Build Coastguard Worker    for partition_dir in ('%s/' % partition.upper(), 'SYSTEM/%s/' % partition):
303*9e94795aSAndroid Build Coastguard Worker      if partition_dir in input_namelist:
304*9e94795aSAndroid Build Coastguard Worker        fs_type_prefix = '' if partition == 'system' else '%s_' % partition
305*9e94795aSAndroid Build Coastguard Worker        keys.extend([
306*9e94795aSAndroid Build Coastguard Worker            'avb_%s_hashtree_enable' % partition,
307*9e94795aSAndroid Build Coastguard Worker            'avb_%s_add_hashtree_footer_args' % partition,
308*9e94795aSAndroid Build Coastguard Worker            '%s_disable_sparse' % partition,
309*9e94795aSAndroid Build Coastguard Worker            'building_%s_image' % partition,
310*9e94795aSAndroid Build Coastguard Worker            '%sfs_type' % fs_type_prefix,
311*9e94795aSAndroid Build Coastguard Worker        ])
312*9e94795aSAndroid Build Coastguard Worker
313*9e94795aSAndroid Build Coastguard Worker  return sorted(keys)
314