DynamicPartitionControl: only create snapshot when snapshot_enabled
Do not create snapshot when applying downgrade
to non-Virtual-A/B packages and secondary OTAs.
Test: apply downgrade OTA on Virtual A/B devices
Bug: 138733621 (secondary OTA)
Fixes: 138258570 (downgrades)
Change-Id: I13318f57613d6bd60a5b7e81ebb3e35b3c225a0c
diff --git a/boot_control_android.cc b/boot_control_android.cc
index 4a010bd..b1d775e 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -308,12 +308,8 @@
return true;
}
- if (!update_metadata) {
- return true;
- }
-
return dynamic_control_->PreparePartitionsForUpdate(
- source_slot, target_slot, manifest);
+ source_slot, target_slot, manifest, update_metadata);
}
} // namespace chromeos_update_engine
diff --git a/boot_control_android_unittest.cc b/boot_control_android_unittest.cc
index f090de2..e44af15 100644
--- a/boot_control_android_unittest.cc
+++ b/boot_control_android_unittest.cc
@@ -197,6 +197,9 @@
{T("system"), 2_GiB},
{T("vendor"), 1_GiB}});
+ EXPECT_CALL(dynamicControl(), PreparePartitionsForUpdate(_, _, _, false))
+ .WillOnce(Return(true));
+
EXPECT_TRUE(PreparePartitionsForUpdate(
target(), {{"system", 2_GiB}, {"vendor", 1_GiB}}, false));
diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc
index 8dcf343..88a787a 100644
--- a/dynamic_partition_control_android.cc
+++ b/dynamic_partition_control_android.cc
@@ -112,7 +112,8 @@
.force_writable = force_writable,
};
bool success = false;
- if (GetVirtualAbFeatureFlag().IsEnabled() && force_writable) {
+ if (GetVirtualAbFeatureFlag().IsEnabled() && target_supports_snapshot_ &&
+ force_writable) {
// Only target partitions are mapped with force_writable. On Virtual
// A/B devices, target partitions may overlap with source partitions, so
// they must be mapped with snapshot.
@@ -343,11 +344,15 @@
bool DynamicPartitionControlAndroid::PreparePartitionsForUpdate(
uint32_t source_slot,
uint32_t target_slot,
- const DeltaArchiveManifest& manifest) {
- // TODO(elsk): Also call PrepareDynamicPartitionsForUpdate when applying
- // downgrade packages on retrofit Virtual A/B devices and when applying
- // secondary OTA. b/138258570
- if (GetVirtualAbFeatureFlag().IsEnabled()) {
+ const DeltaArchiveManifest& manifest,
+ bool update) {
+ target_supports_snapshot_ =
+ manifest.dynamic_partition_metadata().snapshot_enabled();
+
+ if (!update)
+ return true;
+
+ if (GetVirtualAbFeatureFlag().IsEnabled() && target_supports_snapshot_) {
return PrepareSnapshotPartitionsForUpdate(
source_slot, target_slot, manifest);
}
@@ -491,10 +496,11 @@
}
bool DynamicPartitionControlAndroid::FinishUpdate() {
- if (!GetVirtualAbFeatureFlag().IsEnabled())
- return true;
- LOG(INFO) << "Snapshot writes are done.";
- return snapshot_->FinishedSnapshotWrites();
+ if (GetVirtualAbFeatureFlag().IsEnabled() && target_supports_snapshot_) {
+ LOG(INFO) << "Snapshot writes are done.";
+ return snapshot_->FinishedSnapshotWrites();
+ }
+ return true;
}
} // namespace chromeos_update_engine
diff --git a/dynamic_partition_control_android.h b/dynamic_partition_control_android.h
index f9dfd89..35d8216 100644
--- a/dynamic_partition_control_android.h
+++ b/dynamic_partition_control_android.h
@@ -46,10 +46,10 @@
std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder(
const std::string& super_device, uint32_t source_slot) override;
- bool PreparePartitionsForUpdate(
- uint32_t source_slot,
- uint32_t target_slot,
- const DeltaArchiveManifest& manifest) override;
+ bool PreparePartitionsForUpdate(uint32_t source_slot,
+ uint32_t target_slot,
+ const DeltaArchiveManifest& manifest,
+ bool update) override;
bool GetDeviceDir(std::string* path) override;
std::string GetSuperPartitionName(uint32_t slot) override;
bool FinishUpdate() override;
@@ -113,6 +113,7 @@
std::set<std::string> mapped_devices_;
std::unique_ptr<android::snapshot::SnapshotManager> snapshot_;
+ bool target_supports_snapshot_ = false;
DISALLOW_COPY_AND_ASSIGN(DynamicPartitionControlAndroid);
};
diff --git a/dynamic_partition_control_android_unittest.cc b/dynamic_partition_control_android_unittest.cc
index 552774e..e8ef1f9 100644
--- a/dynamic_partition_control_android_unittest.cc
+++ b/dynamic_partition_control_android_unittest.cc
@@ -112,7 +112,7 @@
}
bool PreparePartitionsForUpdate(const PartitionSizes& partition_sizes) {
return dynamicControl().PreparePartitionsForUpdate(
- source(), target(), PartitionSizesToManifest(partition_sizes));
+ source(), target(), PartitionSizesToManifest(partition_sizes), true);
}
void SetSlots(const TestParam& slots) { slots_ = slots; }
diff --git a/dynamic_partition_control_interface.h b/dynamic_partition_control_interface.h
index 0ccfcd6..9c4c2e8 100644
--- a/dynamic_partition_control_interface.h
+++ b/dynamic_partition_control_interface.h
@@ -92,10 +92,11 @@
// Prepare all partitions for an update specified in |manifest|.
// This is needed before calling MapPartitionOnDeviceMapper(), otherwise the
// device would be mapped in an inconsistent way.
- virtual bool PreparePartitionsForUpdate(
- uint32_t source_slot,
- uint32_t target_slot,
- const DeltaArchiveManifest& manifest) = 0;
+ // If |update| is set, create snapshots and writes super partition metadata.
+ virtual bool PreparePartitionsForUpdate(uint32_t source_slot,
+ uint32_t target_slot,
+ const DeltaArchiveManifest& manifest,
+ bool update) = 0;
// Return a possible location for devices listed by name.
virtual bool GetDeviceDir(std::string* path) = 0;
diff --git a/mock_dynamic_partition_control.h b/mock_dynamic_partition_control.h
index 1af6cfe..8146e0f 100644
--- a/mock_dynamic_partition_control.h
+++ b/mock_dynamic_partition_control.h
@@ -44,8 +44,8 @@
const std::string&, uint32_t));
MOCK_METHOD1(GetDeviceDir, bool(std::string*));
MOCK_METHOD0(GetDynamicPartitionsFeatureFlag, FeatureFlag());
- MOCK_METHOD3(PreparePartitionsForUpdate,
- bool(uint32_t, uint32_t, const DeltaArchiveManifest&));
+ MOCK_METHOD4(PreparePartitionsForUpdate,
+ bool(uint32_t, uint32_t, const DeltaArchiveManifest&, bool));
MOCK_METHOD1(GetSuperPartitionName, std::string(uint32_t));
MOCK_METHOD0(GetVirtualAbFeatureFlag, FeatureFlag());
MOCK_METHOD0(FinishUpdate, bool());