Loading tools/releasetools/ota_from_target_files.py +59 −1 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'OTA/*', 'RADIO/*'] TARGET_DIFFING_UNZIP_PATTERN = ['BOOT', 'RECOVERY', 'SYSTEM/*', 'VENDOR/*', 'PRODUCT/*', 'SYSTEM_EXT/*', 'ODM/*'] RETROFIT_DAP_UNZIP_PATTERN = ['OTA/super_*.img', AB_PARTITIONS] SECONDARY_IMAGES_SKIP_PARTITIONS = ['odm', 'product', 'system_ext', 'vendor'] class BuildInfo(object): Loading Loading @@ -1792,6 +1793,43 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): Returns: The filename of the target-files.zip for generating secondary payload. """ def GetInfoForSecondaryImages(info_file): """Updates info file for secondary payload generation. Scan each line in the info file, and remove the unwanted partitions from the dynamic partition list in the related properties. e.g. "super_google_dynamic_partitions_partition_list=system vendor product" will become "super_google_dynamic_partitions_partition_list=system". Args: info_file: The input info file. e.g. misc_info.txt. Returns: A string of the updated info content. """ output_list = [] with open(info_file) as f: lines = f.read().splitlines() # The suffix in partition_list variables that follows the name of the # partition group. LIST_SUFFIX = 'partition_list' for line in lines: if line.startswith('#') or '=' not in line: output_list.append(line) continue key, value = line.strip().split('=', 1) if key == 'dynamic_partition_list' or key.endswith(LIST_SUFFIX): partitions = value.split() partitions = [partition for partition in partitions if partition not in SECONDARY_IMAGES_SKIP_PARTITIONS] output_list.append('{}={}'.format(key, ' '.join(partitions))) else: output_list.append(line) return '\n'.join(output_list) target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip") target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True) Loading @@ -1808,12 +1846,32 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): elif info.filename in ('IMAGES/system.img', 'IMAGES/system.map'): pass # Images like vendor and product are not needed in the secondary payload. elif info.filename in ['IMAGES/{}.img'.format(partition) for partition in SECONDARY_IMAGES_SKIP_PARTITIONS]: pass # Skip copying the postinstall config if requested. elif skip_postinstall and info.filename == POSTINSTALL_CONFIG: pass elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')): elif info.filename.startswith('META/'): # Remove the unnecessary partitions for secondary images from the # ab_partitions file. if info.filename == AB_PARTITIONS: with open(unzipped_file) as f: partition_list = f.read().splitlines() partition_list = [partition for partition in partition_list if partition and partition not in SECONDARY_IMAGES_SKIP_PARTITIONS] common.ZipWriteStr(target_zip, info.filename, '\n'.join(partition_list)) # Remove the unnecessary partitions from the dynamic partitions list. elif (info.filename == 'META/misc_info.txt' or info.filename == DYNAMIC_PARTITION_INFO): modified_info = GetInfoForSecondaryImages(unzipped_file) common.ZipWriteStr(target_zip, info.filename, modified_info) else: common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) elif info.filename.startswith(('IMAGES/', 'RADIO/')): common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) common.ZipClose(target_zip) Loading tools/releasetools/test_ota_from_target_files.py +53 −3 Original line number Diff line number Diff line Loading @@ -588,11 +588,11 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(target_file) as verify_zip: namelist = verify_zip.namelist() ab_partitions = verify_zip.read('META/ab_partitions.txt') self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) self.assertIn('RADIO/modem.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) Loading @@ -600,6 +600,9 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) expected_ab_partitions = ['boot', 'system', 'bootloader', 'modem'] self.assertEqual('\n'.join(expected_ab_partitions), ab_partitions) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self): input_file = construct_target_files(secondary=True) Loading @@ -612,7 +615,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) self.assertIn('RADIO/modem.img', namelist) Loading @@ -633,7 +635,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) self.assertNotIn('IMAGES/system_other.img', namelist) Loading @@ -641,6 +642,55 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('RADIO/bootloader.img', namelist) self.assertNotIn('RADIO/modem.img', namelist) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_dynamicPartitions(self): input_file = construct_target_files(secondary=True) misc_info = '\n'.join([ 'use_dynamic_partition_size=true', 'use_dynamic_partitions=true', 'dynamic_partition_list=system vendor product', 'super_partition_groups=google_dynamic_partitions', 'super_google_dynamic_partitions_group_size=4873781248', 'super_google_dynamic_partitions_partition_list=system vendor product', ]) dynamic_partitions_info = '\n'.join([ 'super_partition_groups=google_dynamic_partitions', 'super_google_dynamic_partitions_group_size=4873781248', 'super_google_dynamic_partitions_partition_list=system vendor product', ]) with zipfile.ZipFile(input_file, 'a') as append_zip: common.ZipWriteStr(append_zip, 'META/misc_info.txt', misc_info) common.ZipWriteStr(append_zip, 'META/dynamic_partitions_info.txt', dynamic_partitions_info) target_file = GetTargetFilesZipForSecondaryImages(input_file) with zipfile.ZipFile(target_file) as verify_zip: namelist = verify_zip.namelist() updated_misc_info = verify_zip.read('META/misc_info.txt') updated_dynamic_partitions_info = verify_zip.read( 'META/dynamic_partitions_info.txt') self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) self.assertIn('META/misc_info.txt', namelist) self.assertIn('META/dynamic_partitions_info.txt', namelist) self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) # Check the vendor & product are removed from the partitions list. expected_misc_info = misc_info.replace('system vendor product', 'system') expected_dynamic_partitions_info = dynamic_partitions_info.replace( 'system vendor product', 'system') self.assertEqual(expected_misc_info, updated_misc_info) self.assertEqual(expected_dynamic_partitions_info, updated_dynamic_partitions_info) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipWithoutPostinstallConfig(self): input_file = construct_target_files() Loading Loading
tools/releasetools/ota_from_target_files.py +59 −1 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'OTA/*', 'RADIO/*'] TARGET_DIFFING_UNZIP_PATTERN = ['BOOT', 'RECOVERY', 'SYSTEM/*', 'VENDOR/*', 'PRODUCT/*', 'SYSTEM_EXT/*', 'ODM/*'] RETROFIT_DAP_UNZIP_PATTERN = ['OTA/super_*.img', AB_PARTITIONS] SECONDARY_IMAGES_SKIP_PARTITIONS = ['odm', 'product', 'system_ext', 'vendor'] class BuildInfo(object): Loading Loading @@ -1792,6 +1793,43 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): Returns: The filename of the target-files.zip for generating secondary payload. """ def GetInfoForSecondaryImages(info_file): """Updates info file for secondary payload generation. Scan each line in the info file, and remove the unwanted partitions from the dynamic partition list in the related properties. e.g. "super_google_dynamic_partitions_partition_list=system vendor product" will become "super_google_dynamic_partitions_partition_list=system". Args: info_file: The input info file. e.g. misc_info.txt. Returns: A string of the updated info content. """ output_list = [] with open(info_file) as f: lines = f.read().splitlines() # The suffix in partition_list variables that follows the name of the # partition group. LIST_SUFFIX = 'partition_list' for line in lines: if line.startswith('#') or '=' not in line: output_list.append(line) continue key, value = line.strip().split('=', 1) if key == 'dynamic_partition_list' or key.endswith(LIST_SUFFIX): partitions = value.split() partitions = [partition for partition in partitions if partition not in SECONDARY_IMAGES_SKIP_PARTITIONS] output_list.append('{}={}'.format(key, ' '.join(partitions))) else: output_list.append(line) return '\n'.join(output_list) target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip") target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True) Loading @@ -1808,12 +1846,32 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): elif info.filename in ('IMAGES/system.img', 'IMAGES/system.map'): pass # Images like vendor and product are not needed in the secondary payload. elif info.filename in ['IMAGES/{}.img'.format(partition) for partition in SECONDARY_IMAGES_SKIP_PARTITIONS]: pass # Skip copying the postinstall config if requested. elif skip_postinstall and info.filename == POSTINSTALL_CONFIG: pass elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')): elif info.filename.startswith('META/'): # Remove the unnecessary partitions for secondary images from the # ab_partitions file. if info.filename == AB_PARTITIONS: with open(unzipped_file) as f: partition_list = f.read().splitlines() partition_list = [partition for partition in partition_list if partition and partition not in SECONDARY_IMAGES_SKIP_PARTITIONS] common.ZipWriteStr(target_zip, info.filename, '\n'.join(partition_list)) # Remove the unnecessary partitions from the dynamic partitions list. elif (info.filename == 'META/misc_info.txt' or info.filename == DYNAMIC_PARTITION_INFO): modified_info = GetInfoForSecondaryImages(unzipped_file) common.ZipWriteStr(target_zip, info.filename, modified_info) else: common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) elif info.filename.startswith(('IMAGES/', 'RADIO/')): common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) common.ZipClose(target_zip) Loading
tools/releasetools/test_ota_from_target_files.py +53 −3 Original line number Diff line number Diff line Loading @@ -588,11 +588,11 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(target_file) as verify_zip: namelist = verify_zip.namelist() ab_partitions = verify_zip.read('META/ab_partitions.txt') self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) self.assertIn('RADIO/modem.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) Loading @@ -600,6 +600,9 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) expected_ab_partitions = ['boot', 'system', 'bootloader', 'modem'] self.assertEqual('\n'.join(expected_ab_partitions), ab_partitions) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self): input_file = construct_target_files(secondary=True) Loading @@ -612,7 +615,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) self.assertIn('RADIO/modem.img', namelist) Loading @@ -633,7 +635,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn('IMAGES/vendor.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) self.assertNotIn('IMAGES/system_other.img', namelist) Loading @@ -641,6 +642,55 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('RADIO/bootloader.img', namelist) self.assertNotIn('RADIO/modem.img', namelist) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_dynamicPartitions(self): input_file = construct_target_files(secondary=True) misc_info = '\n'.join([ 'use_dynamic_partition_size=true', 'use_dynamic_partitions=true', 'dynamic_partition_list=system vendor product', 'super_partition_groups=google_dynamic_partitions', 'super_google_dynamic_partitions_group_size=4873781248', 'super_google_dynamic_partitions_partition_list=system vendor product', ]) dynamic_partitions_info = '\n'.join([ 'super_partition_groups=google_dynamic_partitions', 'super_google_dynamic_partitions_group_size=4873781248', 'super_google_dynamic_partitions_partition_list=system vendor product', ]) with zipfile.ZipFile(input_file, 'a') as append_zip: common.ZipWriteStr(append_zip, 'META/misc_info.txt', misc_info) common.ZipWriteStr(append_zip, 'META/dynamic_partitions_info.txt', dynamic_partitions_info) target_file = GetTargetFilesZipForSecondaryImages(input_file) with zipfile.ZipFile(target_file) as verify_zip: namelist = verify_zip.namelist() updated_misc_info = verify_zip.read('META/misc_info.txt') updated_dynamic_partitions_info = verify_zip.read( 'META/dynamic_partitions_info.txt') self.assertIn('META/ab_partitions.txt', namelist) self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) self.assertIn('META/misc_info.txt', namelist) self.assertIn('META/dynamic_partitions_info.txt', namelist) self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) # Check the vendor & product are removed from the partitions list. expected_misc_info = misc_info.replace('system vendor product', 'system') expected_dynamic_partitions_info = dynamic_partitions_info.replace( 'system vendor product', 'system') self.assertEqual(expected_misc_info, updated_misc_info) self.assertEqual(expected_dynamic_partitions_info, updated_dynamic_partitions_info) @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipWithoutPostinstallConfig(self): input_file = construct_target_files() Loading