Loading tools/releasetools/add_img_to_target_files.py +3 −2 Original line number Diff line number Diff line Loading @@ -420,8 +420,9 @@ def CreateImage(input_dir, info_dict, what, output_file, block_list=None): image_props["block_list"] = block_list.name # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and # build fingerprint). build_info = common.BuildInfo(info_dict) # build fingerprint). Also use the legacy build id, because the vbmeta digest # isn't available at this point. build_info = common.BuildInfo(info_dict, use_legacy_id=True) uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what) image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed)) hash_seed = "hash_seed-" + uuid_seed Loading tools/releasetools/common.py +48 −3 Original line number Diff line number Diff line Loading @@ -372,7 +372,10 @@ class BuildInfo(object): "product", "product_services", "odm", "vendor", "system"] _RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = [] def __init__(self, info_dict, oem_dicts=None): # The length of vbmeta digest to append to the fingerprint _VBMETA_DIGEST_SIZE_USED = 8 def __init__(self, info_dict, oem_dicts=None, use_legacy_id=False): """Initializes a BuildInfo instance with the given dicts. Note that it only wraps up the given dicts, without making copies. Loading @@ -383,6 +386,9 @@ class BuildInfo(object): that it always uses the first dict to calculate the fingerprint or the device name. The rest would be used for asserting OEM properties only (e.g. one package can be installed on one of these devices). use_legacy_id: Use the legacy build id to construct the fingerprint. This is used when we need a BuildInfo class, while the vbmeta digest is unavailable. Raises: ValueError: On invalid inputs. Loading @@ -391,6 +397,7 @@ class BuildInfo(object): self.oem_dicts = oem_dicts self._is_ab = info_dict.get("ab_update") == "true" self.use_legacy_id = use_legacy_id # Skip _oem_props if oem_dicts is None to use BuildInfo in # sign_target_files_apks Loading Loading @@ -491,6 +498,9 @@ class BuildInfo(object): if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS: return self._ResolveRoProductBuildProp(prop) if prop == "ro.build.id": return self._GetBuildId() prop_val = self._GetRawBuildProp(prop, None) if prop_val is not None: return prop_val Loading Loading @@ -557,6 +567,34 @@ class BuildInfo(object): return self.GetBuildProp("ro.build.version.release") def _GetBuildId(self): build_id = self._GetRawBuildProp("ro.build.id", None) if build_id: return build_id legacy_build_id = self.GetBuildProp("ro.build.legacy.id") if not legacy_build_id: raise ExternalError("Couldn't find build id in property file") if self.use_legacy_id: return legacy_build_id # Append the top 8 chars of vbmeta digest to the existing build id. The # logic needs to match the one in init, so that OTA can deliver correctly. avb_enable = self.info_dict.get("avb_enable") == "true" if not avb_enable: raise ExternalError("AVB isn't enabled when using legacy build id") vbmeta_digest = self.info_dict.get("vbmeta_digest") if not vbmeta_digest: raise ExternalError("Vbmeta digest isn't provided when using legacy build" " id") if len(vbmeta_digest) < self._VBMETA_DIGEST_SIZE_USED: raise ExternalError("Invalid vbmeta digest " + vbmeta_digest) digest_prefix = vbmeta_digest[:self._VBMETA_DIGEST_SIZE_USED] return legacy_build_id + '.' + digest_prefix def _GetPartitionPlatformVersion(self, partition): try: return self.GetPartitionBuildProp("ro.build.version.release_or_codename", Loading Loading @@ -790,12 +828,19 @@ def LoadInfoDict(input_file, repacking=False): # Set up the salt (based on fingerprint) that will be used when adding AVB # hash / hashtree footers. if d.get("avb_enable") == "true": build_info = BuildInfo(d) build_info = BuildInfo(d, use_legacy_id=True) for partition in PARTITIONS_WITH_BUILD_PROP: fingerprint = build_info.GetPartitionFingerprint(partition) if fingerprint: d["avb_{}_salt".format(partition)] = sha256( fingerprint.encode()).hexdigest() # Set the vbmeta digest if exists try: d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip() except KeyError: pass try: d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n") except KeyError: Loading Loading @@ -1339,7 +1384,7 @@ def ConstructAftlMakeImageCommands(output_image): vbmeta_image = MakeTempFile() os.rename(output_image, vbmeta_image) build_info = BuildInfo(OPTIONS.info_dict) build_info = BuildInfo(OPTIONS.info_dict, use_legacy_id=True) version_incremental = build_info.GetBuildProp("ro.build.version.incremental") aftltool = OPTIONS.aftl_tool_path server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path] Loading tools/releasetools/test_common.py +43 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,22 @@ def get_2gb_string(): class BuildInfoTest(test_utils.ReleaseToolsTestCase): TEST_INFO_FINGERPRINT_DICT = { 'build.prop': common.PartitionBuildProps.FromDictionary( 'system', { 'ro.product.brand': 'product-brand', 'ro.product.name': 'product-name', 'ro.product.device': 'product-device', 'ro.build.version.release': 'version-release', 'ro.build.id': 'build-id', 'ro.build.version.incremental': 'version-incremental', 'ro.build.type': 'build-type', 'ro.build.tags': 'build-tags', 'ro.build.version.sdk': 30, } ), } TEST_INFO_DICT = { 'build.prop': common.PartitionBuildProps.FromDictionary( 'system', { Loading Loading @@ -202,6 +218,33 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): 'ro.build.fingerprint'] = 'bad\x80fingerprint' self.assertRaises(ValueError, common.BuildInfo, info_dict, None) def test_init_goodFingerprint(self): info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT) build_info = common.BuildInfo(info_dict) self.assertEqual( 'product-brand/product-name/product-device:version-release/build-id/' 'version-incremental:build-type/build-tags', build_info.fingerprint) build_props = info_dict['build.prop'].build_props del build_props['ro.build.id'] build_props['ro.build.legacy.id'] = 'legacy-build-id' build_info = common.BuildInfo(info_dict, use_legacy_id=True) self.assertEqual( 'product-brand/product-name/product-device:version-release/' 'legacy-build-id/version-incremental:build-type/build-tags', build_info.fingerprint) self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None, False) info_dict['avb_enable'] = 'true' info_dict['vbmeta_digest'] = 'abcde12345' build_info = common.BuildInfo(info_dict, use_legacy_id=False) self.assertEqual( 'product-brand/product-name/product-device:version-release/' 'legacy-build-id.abcde123/version-incremental:build-type/build-tags', build_info.fingerprint) def test___getitem__(self): target_info = common.BuildInfo(self.TEST_INFO_DICT, None) self.assertEqual('value1', target_info['property1']) Loading Loading
tools/releasetools/add_img_to_target_files.py +3 −2 Original line number Diff line number Diff line Loading @@ -420,8 +420,9 @@ def CreateImage(input_dir, info_dict, what, output_file, block_list=None): image_props["block_list"] = block_list.name # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and # build fingerprint). build_info = common.BuildInfo(info_dict) # build fingerprint). Also use the legacy build id, because the vbmeta digest # isn't available at this point. build_info = common.BuildInfo(info_dict, use_legacy_id=True) uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what) image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed)) hash_seed = "hash_seed-" + uuid_seed Loading
tools/releasetools/common.py +48 −3 Original line number Diff line number Diff line Loading @@ -372,7 +372,10 @@ class BuildInfo(object): "product", "product_services", "odm", "vendor", "system"] _RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = [] def __init__(self, info_dict, oem_dicts=None): # The length of vbmeta digest to append to the fingerprint _VBMETA_DIGEST_SIZE_USED = 8 def __init__(self, info_dict, oem_dicts=None, use_legacy_id=False): """Initializes a BuildInfo instance with the given dicts. Note that it only wraps up the given dicts, without making copies. Loading @@ -383,6 +386,9 @@ class BuildInfo(object): that it always uses the first dict to calculate the fingerprint or the device name. The rest would be used for asserting OEM properties only (e.g. one package can be installed on one of these devices). use_legacy_id: Use the legacy build id to construct the fingerprint. This is used when we need a BuildInfo class, while the vbmeta digest is unavailable. Raises: ValueError: On invalid inputs. Loading @@ -391,6 +397,7 @@ class BuildInfo(object): self.oem_dicts = oem_dicts self._is_ab = info_dict.get("ab_update") == "true" self.use_legacy_id = use_legacy_id # Skip _oem_props if oem_dicts is None to use BuildInfo in # sign_target_files_apks Loading Loading @@ -491,6 +498,9 @@ class BuildInfo(object): if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS: return self._ResolveRoProductBuildProp(prop) if prop == "ro.build.id": return self._GetBuildId() prop_val = self._GetRawBuildProp(prop, None) if prop_val is not None: return prop_val Loading Loading @@ -557,6 +567,34 @@ class BuildInfo(object): return self.GetBuildProp("ro.build.version.release") def _GetBuildId(self): build_id = self._GetRawBuildProp("ro.build.id", None) if build_id: return build_id legacy_build_id = self.GetBuildProp("ro.build.legacy.id") if not legacy_build_id: raise ExternalError("Couldn't find build id in property file") if self.use_legacy_id: return legacy_build_id # Append the top 8 chars of vbmeta digest to the existing build id. The # logic needs to match the one in init, so that OTA can deliver correctly. avb_enable = self.info_dict.get("avb_enable") == "true" if not avb_enable: raise ExternalError("AVB isn't enabled when using legacy build id") vbmeta_digest = self.info_dict.get("vbmeta_digest") if not vbmeta_digest: raise ExternalError("Vbmeta digest isn't provided when using legacy build" " id") if len(vbmeta_digest) < self._VBMETA_DIGEST_SIZE_USED: raise ExternalError("Invalid vbmeta digest " + vbmeta_digest) digest_prefix = vbmeta_digest[:self._VBMETA_DIGEST_SIZE_USED] return legacy_build_id + '.' + digest_prefix def _GetPartitionPlatformVersion(self, partition): try: return self.GetPartitionBuildProp("ro.build.version.release_or_codename", Loading Loading @@ -790,12 +828,19 @@ def LoadInfoDict(input_file, repacking=False): # Set up the salt (based on fingerprint) that will be used when adding AVB # hash / hashtree footers. if d.get("avb_enable") == "true": build_info = BuildInfo(d) build_info = BuildInfo(d, use_legacy_id=True) for partition in PARTITIONS_WITH_BUILD_PROP: fingerprint = build_info.GetPartitionFingerprint(partition) if fingerprint: d["avb_{}_salt".format(partition)] = sha256( fingerprint.encode()).hexdigest() # Set the vbmeta digest if exists try: d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip() except KeyError: pass try: d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n") except KeyError: Loading Loading @@ -1339,7 +1384,7 @@ def ConstructAftlMakeImageCommands(output_image): vbmeta_image = MakeTempFile() os.rename(output_image, vbmeta_image) build_info = BuildInfo(OPTIONS.info_dict) build_info = BuildInfo(OPTIONS.info_dict, use_legacy_id=True) version_incremental = build_info.GetBuildProp("ro.build.version.incremental") aftltool = OPTIONS.aftl_tool_path server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path] Loading
tools/releasetools/test_common.py +43 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,22 @@ def get_2gb_string(): class BuildInfoTest(test_utils.ReleaseToolsTestCase): TEST_INFO_FINGERPRINT_DICT = { 'build.prop': common.PartitionBuildProps.FromDictionary( 'system', { 'ro.product.brand': 'product-brand', 'ro.product.name': 'product-name', 'ro.product.device': 'product-device', 'ro.build.version.release': 'version-release', 'ro.build.id': 'build-id', 'ro.build.version.incremental': 'version-incremental', 'ro.build.type': 'build-type', 'ro.build.tags': 'build-tags', 'ro.build.version.sdk': 30, } ), } TEST_INFO_DICT = { 'build.prop': common.PartitionBuildProps.FromDictionary( 'system', { Loading Loading @@ -202,6 +218,33 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): 'ro.build.fingerprint'] = 'bad\x80fingerprint' self.assertRaises(ValueError, common.BuildInfo, info_dict, None) def test_init_goodFingerprint(self): info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT) build_info = common.BuildInfo(info_dict) self.assertEqual( 'product-brand/product-name/product-device:version-release/build-id/' 'version-incremental:build-type/build-tags', build_info.fingerprint) build_props = info_dict['build.prop'].build_props del build_props['ro.build.id'] build_props['ro.build.legacy.id'] = 'legacy-build-id' build_info = common.BuildInfo(info_dict, use_legacy_id=True) self.assertEqual( 'product-brand/product-name/product-device:version-release/' 'legacy-build-id/version-incremental:build-type/build-tags', build_info.fingerprint) self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None, False) info_dict['avb_enable'] = 'true' info_dict['vbmeta_digest'] = 'abcde12345' build_info = common.BuildInfo(info_dict, use_legacy_id=False) self.assertEqual( 'product-brand/product-name/product-device:version-release/' 'legacy-build-id.abcde123/version-incremental:build-type/build-tags', build_info.fingerprint) def test___getitem__(self): target_info = common.BuildInfo(self.TEST_INFO_DICT, None) self.assertEqual('value1', target_info['property1']) Loading