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