Detect downgrade by checking build time for all partitions
Checking ro.build.date.utc to detect a downgrade is not enough in the
case where several target files are merged, as timestamps can differ
for each partition.
The solution is to check the build timestamp for each partition and
ro.build.date.utc.
With this change ota generation will be aborted during creation
instead of rejected when installing on device.
This also fixes the --override_timestamp so it is possible to generate
a package where timestamps are reversed, as was added in:
3e6161a3b33da5a46c80c79e2d815168923e83c3.
Issue: 315913966
Test: Manual, confirm that ota generation is aborted when timestamp
on post vendor partitions is newer than on pre.
Ota created successfully with --override_timestamp parameter and
installation successful
Test: atest --host releasetools_test
Change-Id: I275e67a3840f4ef2263381c253231068e72f47d2
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index ad0f7a8..d1e76b9 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -163,6 +163,20 @@
'oem_fingerprint_properties': 'ro.product.device ro.product.brand',
}
+ TEST_TARGET_VENDOR_INFO_DICT = common.PartitionBuildProps.FromDictionary(
+ 'vendor', {
+ 'ro.vendor.build.date.utc' : '87654321',
+ 'ro.product.vendor.device':'vendor-device',
+ 'ro.vendor.build.fingerprint': 'build-fingerprint-vendor'}
+ )
+
+ TEST_SOURCE_VENDOR_INFO_DICT = common.PartitionBuildProps.FromDictionary(
+ 'vendor', {
+ 'ro.vendor.build.date.utc' : '12345678',
+ 'ro.product.vendor.device':'vendor-device',
+ 'ro.vendor.build.fingerprint': 'build-fingerprint-vendor'}
+ )
+
def setUp(self):
self.testdata_dir = test_utils.get_testdata_dir()
self.assertTrue(os.path.exists(self.testdata_dir))
@@ -351,6 +365,13 @@
source_info['build.prop'].build_props['ro.build.date.utc'],
target_info['build.prop'].build_props['ro.build.date.utc'])
+ @staticmethod
+ def _test_GetPackageMetadata_swapVendorBuildTimestamps(target_info, source_info):
+ (target_info['vendor.build.prop'].build_props['ro.vendor.build.date.utc'],
+ source_info['vendor.build.prop'].build_props['ro.vendor.build.date.utc']) = (
+ source_info['vendor.build.prop'].build_props['ro.vendor.build.date.utc'],
+ target_info['vendor.build.prop'].build_props['ro.vendor.build.date.utc'])
+
def test_GetPackageMetadata_unintentionalDowngradeDetected(self):
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
@@ -363,6 +384,24 @@
self.assertRaises(RuntimeError, self.GetLegacyOtaMetadata, target_info,
source_info)
+ def test_GetPackageMetadata_unintentionalVendorDowngradeDetected(self):
+ target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
+ target_info_dict['ab_update'] = 'true'
+ target_info_dict['ab_partitions'] = ['vendor']
+ target_info_dict["vendor.build.prop"] = copy.deepcopy(self.TEST_TARGET_VENDOR_INFO_DICT)
+ source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
+ source_info_dict['ab_update'] = 'true'
+ source_info_dict['ab_partitions'] = ['vendor']
+ source_info_dict["vendor.build.prop"] = copy.deepcopy(self.TEST_SOURCE_VENDOR_INFO_DICT)
+ self._test_GetPackageMetadata_swapVendorBuildTimestamps(
+ target_info_dict, source_info_dict)
+
+ target_info = common.BuildInfo(target_info_dict, None)
+ source_info = common.BuildInfo(source_info_dict, None)
+ common.OPTIONS.incremental_source = ''
+ self.assertRaises(RuntimeError, self.GetLegacyOtaMetadata, target_info,
+ source_info)
+
def test_GetPackageMetadata_downgrade(self):
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
@@ -397,6 +436,55 @@
},
metadata)
+ def test_GetPackageMetadata_vendorDowngrade(self):
+ target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
+ target_info_dict['ab_update'] = 'true'
+ target_info_dict['ab_partitions'] = ['vendor']
+ target_info_dict["vendor.build.prop"] = copy.deepcopy(self.TEST_TARGET_VENDOR_INFO_DICT)
+ source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
+ source_info_dict['ab_update'] = 'true'
+ source_info_dict['ab_partitions'] = ['vendor']
+ source_info_dict["vendor.build.prop"] = copy.deepcopy(self.TEST_SOURCE_VENDOR_INFO_DICT)
+ self._test_GetPackageMetadata_swapVendorBuildTimestamps(
+ target_info_dict, source_info_dict)
+
+ target_info = common.BuildInfo(target_info_dict, None)
+ source_info = common.BuildInfo(source_info_dict, None)
+ common.OPTIONS.incremental_source = ''
+ common.OPTIONS.downgrade = True
+ common.OPTIONS.wipe_user_data = True
+ common.OPTIONS.spl_downgrade = True
+ metadata = self.GetLegacyOtaMetadata(target_info, source_info)
+ # Reset spl_downgrade so other tests are unaffected
+ common.OPTIONS.spl_downgrade = False
+
+ self.assertDictEqual(
+ {
+ 'ota-downgrade': 'yes',
+ 'ota-type': 'AB',
+ 'ota-required-cache': '0',
+ 'ota-wipe': 'yes',
+ 'post-build': 'build-fingerprint-target',
+ 'post-build-incremental': 'build-version-incremental-target',
+ 'post-sdk-level': '27',
+ 'post-security-patch-level': '2017-12-01',
+ 'post-timestamp': '1500000000',
+ 'pre-device': 'product-device',
+ 'pre-build': 'build-fingerprint-source',
+ 'pre-build-incremental': 'build-version-incremental-source',
+ 'spl-downgrade': 'yes',
+ },
+ metadata)
+
+ post_build = GetPackageMetadata(target_info, source_info).postcondition
+ self.assertEqual('vendor', post_build.partition_state[0].partition_name)
+ self.assertEqual('12345678', post_build.partition_state[0].version)
+
+ pre_build = GetPackageMetadata(target_info, source_info).precondition
+ self.assertEqual('vendor', pre_build.partition_state[0].partition_name)
+ self.assertEqual('87654321', pre_build.partition_state[0].version)
+
+
@test_utils.SkipIfExternalToolsUnavailable()
def test_GetTargetFilesZipForSecondaryImages(self):
input_file = construct_target_files(secondary=True)