Reland "Calculate the runtime fingerprint prefixes from build prop"
This reverts commit b21e48b499850bfb5ac9e6e155ed96e8e724c5c0.
In practice, some partners use the 'import' statement to override
the device fingerprint at runtime. The runtime fingerprint will
later add to the metadata of OTA package, so that the OTA server
can deliver the package to corresponding devices correctly.
This CL supports parsing a subset of import statement that the init
process recognizes. And we loose the restriction based on how the
dynamic fingerprint is used in practice. Right now, we only searches
for the override of brand, name and device. And the placeholder
format should be ${placeholder}, with its value supplied by the
script caller.
As part of the implementation, we generate all the possible
combinations of the input boot variables. And recalculate the
fingerprint for each of the combination. Though we load the
build.prop multiple times, the logic is easier to follow. Also,
it's more convenient to enhance the logic if we only want to
allow some of the boot variables combination later.
Bug: 152167826
Change-Id: I4a9fa35c7ac037ff1cf4f9a4bdff602beac3894b
Test: unittests pass
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index e007863..4077d06 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -26,7 +26,8 @@
GetPackageMetadata, GetTargetFilesZipForSecondaryImages,
GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
- StreamingPropertyFiles, WriteFingerprintAssertion)
+ StreamingPropertyFiles, WriteFingerprintAssertion,
+ CalculateRuntimeFingerprints)
def construct_target_files(secondary=False):
@@ -1318,3 +1319,125 @@
Payload.SECONDARY_PAYLOAD_PROPERTIES_TXT):
continue
self.assertEqual(zipfile.ZIP_STORED, entry_info.compress_type)
+
+
+class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase):
+ MISC_INFO = [
+ 'recovery_api_version=3',
+ 'fstab_version=2',
+ 'recovery_as_boot=true',
+ ]
+
+ BUILD_PROP = [
+ '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',
+ ]
+
+ VENDOR_BUILD_PROP = [
+ 'ro.product.vendor.brand=vendor-product-brand',
+ 'ro.product.vendor.name=vendor-product-name',
+ 'ro.product.vendor.device=vendor-product-device'
+ ]
+
+ def setUp(self):
+ common.OPTIONS.oem_dicts = None
+ self.test_dir = common.MakeTempDir()
+ self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)})
+
+ def writeFiles(self, contents_dict):
+ for path, content in contents_dict.items():
+ abs_path = os.path.join(self.test_dir, path)
+ dir_name = os.path.dirname(abs_path)
+ if not os.path.exists(dir_name):
+ os.makedirs(dir_name)
+ with open(abs_path, 'w') as f:
+ f.write(content)
+
+ @staticmethod
+ def constructFingerprint(prefix):
+ return '{}:version-release/build-id/version-incremental:' \
+ 'build-type/build-tags'.format(prefix)
+
+ def test_CalculatePossibleFingerprints_no_dynamic_fingerprint(self):
+ build_prop = copy.deepcopy(self.BUILD_PROP)
+ build_prop.extend([
+ 'ro.product.brand=product-brand',
+ 'ro.product.name=product-name',
+ 'ro.product.device=product-device',
+ ])
+ self.writeFiles({
+ 'SYSTEM/build.prop': '\n'.join(build_prop),
+ 'VENDOR/build.prop': '\n'.join(self.VENDOR_BUILD_PROP),
+ })
+ common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
+
+ self.assertEqual({
+ self.constructFingerprint('product-brand/product-name/product-device')
+ }, CalculateRuntimeFingerprints())
+
+ def test_CalculatePossibleFingerprints_single_override(self):
+ vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
+ vendor_build_prop.extend([
+ 'import /vendor/etc/build_${ro.boot.sku_name}.prop',
+ ])
+ self.writeFiles({
+ 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
+ 'VENDOR/build.prop': '\n'.join(vendor_build_prop),
+ 'VENDOR/etc/build_std.prop':
+ 'ro.product.vendor.name=vendor-product-std',
+ 'VENDOR/etc/build_pro.prop':
+ 'ro.product.vendor.name=vendor-product-pro',
+ })
+ common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
+ common.OPTIONS.boot_variable_values = {
+ 'ro.boot.sku_name': ['std', 'pro']
+ }
+
+ self.assertEqual({
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-product-device'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-std/vendor-product-device'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-pro/vendor-product-device'),
+ }, CalculateRuntimeFingerprints())
+
+ def test_CalculatePossibleFingerprints_multiple_overrides(self):
+ vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP)
+ vendor_build_prop.extend([
+ 'import /vendor/etc/build_${ro.boot.sku_name}.prop',
+ 'import /vendor/etc/build_${ro.boot.device_name}.prop',
+ ])
+ self.writeFiles({
+ 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP),
+ 'VENDOR/build.prop': '\n'.join(vendor_build_prop),
+ 'VENDOR/etc/build_std.prop':
+ 'ro.product.vendor.name=vendor-product-std',
+ 'VENDOR/etc/build_product1.prop':
+ 'ro.product.vendor.device=vendor-device-product1',
+ 'VENDOR/etc/build_pro.prop':
+ 'ro.product.vendor.name=vendor-product-pro',
+ 'VENDOR/etc/build_product2.prop':
+ 'ro.product.vendor.device=vendor-device-product2',
+ })
+ common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir)
+ common.OPTIONS.boot_variable_values = {
+ 'ro.boot.sku_name': ['std', 'pro'],
+ 'ro.boot.device_name': ['product1', 'product2'],
+ }
+
+ self.assertEqual({
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-name/vendor-product-device'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-std/vendor-device-product1'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-pro/vendor-device-product1'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-std/vendor-device-product2'),
+ self.constructFingerprint(
+ 'vendor-product-brand/vendor-product-pro/vendor-device-product2'),
+ }, CalculateRuntimeFingerprints())