diff options
| -rwxr-xr-x | tools/releasetools/ota_from_target_files.py | 60 | ||||
| -rw-r--r-- | tools/releasetools/test_ota_from_target_files.py | 56 |
2 files changed, 112 insertions, 4 deletions
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 67cec1c8b7..dc75ce2605 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -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): @@ -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) @@ -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) diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py index ee831e3ae2..0846d87156 100644 --- a/tools/releasetools/test_ota_from_target_files.py +++ b/tools/releasetools/test_ota_from_target_files.py @@ -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) @@ -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) @@ -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) @@ -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) @@ -642,6 +643,55 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): 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() target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file) |