Fix S and T mixed build OTA am: 1c4b981c71 am: 0c7fbe95c8 am: 1d5acb2b6c am: 9a79f4529f am: 98ef4eec48

Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/2058027

Change-Id: Ia908bd16d76d5efd172e1399b15f352615352f67
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/aosp/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc
index e39e7bc..27d1d54 100644
--- a/aosp/dynamic_partition_control_android.cc
+++ b/aosp/dynamic_partition_control_android.cc
@@ -82,6 +82,8 @@
 constexpr char kVirtualAbRetrofit[] = "ro.virtual_ab.retrofit";
 constexpr char kVirtualAbCompressionEnabled[] =
     "ro.virtual_ab.compression.enabled";
+constexpr auto&& kVirtualAbCompressionXorEnabled =
+    "ro.virtual_ab.compression.xor.enabled";
 
 // Currently, android doesn't have a retrofit prop for VAB Compression. However,
 // struct FeatureFlag forces us to determine if a feature is 'retrofit'. So this
@@ -126,6 +128,8 @@
       virtual_ab_(GetFeatureFlag(kVirtualAbEnabled, kVirtualAbRetrofit)),
       virtual_ab_compression_(GetFeatureFlag(kVirtualAbCompressionEnabled,
                                              kVirtualAbCompressionRetrofit)),
+      virtual_ab_compression_xor_(
+          GetFeatureFlag(kVirtualAbCompressionXorEnabled, "")),
       source_slot_(source_slot) {
   if (GetVirtualAbFeatureFlag().IsEnabled()) {
     snapshot_ = SnapshotManager::New();
@@ -152,6 +156,11 @@
   return virtual_ab_compression_;
 }
 
+FeatureFlag
+DynamicPartitionControlAndroid::GetVirtualAbCompressionXorFeatureFlag() {
+  return virtual_ab_compression_xor_;
+}
+
 bool DynamicPartitionControlAndroid::OptimizeOperation(
     const std::string& partition_name,
     const InstallOperation& operation,
diff --git a/aosp/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h
index 457ef18..92761d2 100644
--- a/aosp/dynamic_partition_control_android.h
+++ b/aosp/dynamic_partition_control_android.h
@@ -44,6 +44,7 @@
   FeatureFlag GetDynamicPartitionsFeatureFlag() override;
   FeatureFlag GetVirtualAbFeatureFlag() override;
   FeatureFlag GetVirtualAbCompressionFeatureFlag() override;
+  FeatureFlag GetVirtualAbCompressionXorFeatureFlag() override;
   bool OptimizeOperation(const std::string& partition_name,
                          const InstallOperation& operation,
                          InstallOperation* optimized) override;
@@ -339,6 +340,7 @@
   const FeatureFlag dynamic_partitions_;
   const FeatureFlag virtual_ab_;
   const FeatureFlag virtual_ab_compression_;
+  const FeatureFlag virtual_ab_compression_xor_;
   std::unique_ptr<android::snapshot::ISnapshotManager> snapshot_;
   std::unique_ptr<android::snapshot::AutoDevice> metadata_device_;
   bool target_supports_snapshot_ = false;
diff --git a/aosp/mock_dynamic_partition_control_android.h b/aosp/mock_dynamic_partition_control_android.h
index 33ef39c..f55cdf7 100644
--- a/aosp/mock_dynamic_partition_control_android.h
+++ b/aosp/mock_dynamic_partition_control_android.h
@@ -73,6 +73,10 @@
   MOCK_METHOD(std::string, GetSuperPartitionName, (uint32_t), (override));
   MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override));
   MOCK_METHOD(FeatureFlag, GetVirtualAbCompressionFeatureFlag, (), (override));
+  MOCK_METHOD(FeatureFlag,
+              GetVirtualAbCompressionXorFeatureFlag,
+              (),
+              (override));
   MOCK_METHOD(bool, FinishUpdate, (bool), (override));
   MOCK_METHOD(bool,
               GetSystemOtherPath,
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index e6ebe6a..2c01b1a 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -73,6 +73,8 @@
   // DOES NOT tell you if VABC is used for current OTA update. For that, use
   // UpdateUsesSnapshotCompression.
   virtual FeatureFlag GetVirtualAbCompressionFeatureFlag() = 0;
+  // Return the feature flag for Virtual AB Compression XOR
+  virtual FeatureFlag GetVirtualAbCompressionXorFeatureFlag() = 0;
 
   // Attempt to optimize |operation|.
   // If successful, |optimized| contains an operation with extents that
diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc
index dd30a8b..6283b1d 100644
--- a/common/dynamic_partition_control_stub.cc
+++ b/common/dynamic_partition_control_stub.cc
@@ -38,6 +38,10 @@
   return FeatureFlag(FeatureFlag::Value::NONE);
 }
 
+FeatureFlag DynamicPartitionControlStub::GetVirtualAbCompressionXorFeatureFlag() {
+  return FeatureFlag(FeatureFlag::Value::NONE);
+}
+
 bool DynamicPartitionControlStub::OptimizeOperation(
     const std::string& partition_name,
     const InstallOperation& operation,
diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h
index 5aa4336..15137d2 100644
--- a/common/dynamic_partition_control_stub.h
+++ b/common/dynamic_partition_control_stub.h
@@ -27,11 +27,12 @@
 
 namespace chromeos_update_engine {
 
-class DynamicPartitionControlStub : public DynamicPartitionControlInterface {
+class DynamicPartitionControlStub final : public DynamicPartitionControlInterface {
  public:
   FeatureFlag GetDynamicPartitionsFeatureFlag() override;
   FeatureFlag GetVirtualAbFeatureFlag() override;
   FeatureFlag GetVirtualAbCompressionFeatureFlag() override;
+  FeatureFlag GetVirtualAbCompressionXorFeatureFlag() override;
   bool OptimizeOperation(const std::string& partition_name,
                          const InstallOperation& operation,
                          InstallOperation* optimized) override;
diff --git a/common/mock_dynamic_partition_control.h b/common/mock_dynamic_partition_control.h
index f3a446a..fd0a5a9 100644
--- a/common/mock_dynamic_partition_control.h
+++ b/common/mock_dynamic_partition_control.h
@@ -34,6 +34,10 @@
   MOCK_METHOD(bool, GetDeviceDir, (std::string*), (override));
   MOCK_METHOD(FeatureFlag, GetDynamicPartitionsFeatureFlag, (), (override));
   MOCK_METHOD(FeatureFlag, GetVirtualAbCompressionFeatureFlag, (), (override));
+  MOCK_METHOD(FeatureFlag,
+              GetVirtualAbCompressionXorFeatureFlag,
+              (),
+              (override));
   MOCK_METHOD(FeatureFlag, GetVirtualAbFeatureFlag, (), (override));
   MOCK_METHOD(bool, FinishUpdate, (bool), (override));
   MOCK_METHOD(std::unique_ptr<FileDescriptor>,
diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc
index 54aea86..8ae0b51 100644
--- a/payload_consumer/vabc_partition_writer.cc
+++ b/payload_consumer/vabc_partition_writer.cc
@@ -97,7 +97,17 @@
 bool VABCPartitionWriter::Init(const InstallPlan* install_plan,
                                bool source_may_exist,
                                size_t next_op_index) {
-  xor_map_ = ComputeXorMap(partition_update_.merge_operations());
+  if (dynamic_control_->GetVirtualAbCompressionXorFeatureFlag().IsEnabled()) {
+    xor_map_ = ComputeXorMap(partition_update_.merge_operations());
+    if (xor_map_.size() > 0) {
+      LOG(INFO) << "Virtual AB Compression with XOR is enabled";
+    } else {
+      LOG(INFO) << "Device supports Virtual AB compression with XOR, but OTA "
+                   "package does not.";
+    }
+  } else {
+    LOG(INFO) << "Virtual AB Compression with XOR is disabled.";
+  }
   TEST_AND_RETURN_FALSE(install_plan != nullptr);
   if (source_may_exist && install_part_.source_size > 0) {
     TEST_AND_RETURN_FALSE(!install_part_.source_path.empty());
diff --git a/payload_consumer/vabc_partition_writer_unittest.cc b/payload_consumer/vabc_partition_writer_unittest.cc
index f331091..20aa75f 100644
--- a/payload_consumer/vabc_partition_writer_unittest.cc
+++ b/payload_consumer/vabc_partition_writer_unittest.cc
@@ -48,7 +48,11 @@
 static constexpr size_t FAKE_PART_SIZE = 4096 * 50;
 class VABCPartitionWriterTest : public ::testing::Test {
  public:
-  void SetUp() override { ftruncate(source_part_.fd, FAKE_PART_SIZE); }
+  void SetUp() override {
+    ftruncate(source_part_.fd, FAKE_PART_SIZE);
+    ON_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag())
+        .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::NONE)));
+  }
 
  protected:
   CowMergeOperation* AddMergeOp(PartitionUpdate* partition,
@@ -102,6 +106,8 @@
         ON_CALL(*cow_writer, EmitLabel(_)).WillByDefault(Return(true));
         return cow_writer;
       }));
+  EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag())
+      .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
   ASSERT_TRUE(writer_.Init(&install_plan_, true, 0));
 }
 
@@ -125,6 +131,8 @@
             ON_CALL(*cow_writer, EmitLabel(_)).WillByDefault(Return(true));
             return cow_writer;
           }));
+  EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag())
+      .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
   ASSERT_TRUE(writer_.Init(&install_plan_, true, 0));
 }
 
@@ -224,10 +232,12 @@
             .WillOnce(Return(true));
         return cow_writer;
       }));
+  EXPECT_CALL(dynamic_control_, GetVirtualAbCompressionXorFeatureFlag())
+      .WillRepeatedly(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
   VABCPartitionWriter writer_{
       partition_update_, install_part_, &dynamic_control_, kBlockSize};
   ASSERT_TRUE(writer_.Init(&install_plan_, true, 0));
-  auto patch_data = GetNoopBSDIFF(kBlockSize * 5);
+  const auto patch_data = GetNoopBSDIFF(kBlockSize * 5);
   ASSERT_GT(patch_data.size(), 0UL);
   ASSERT_TRUE(writer_.PerformDiffOperation(
       *install_op, nullptr, patch_data.data(), patch_data.size()));