Don't list dynamic if a slot doesn't support DAP

If a slot doesn't support dynamic partitions, it's impossible to list
dynamic partitions on that slot. And we should just fall back to the
regular A/B in this case.

Bug: 180025432
Test: apply a retrofit package
Change-Id: I16c457b591e8c1d0cf1077a7be50dd9d8f61b8eb
diff --git a/aosp/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc
index c4d6935..a1d5e91 100644
--- a/aosp/dynamic_partition_control_android.cc
+++ b/aosp/dynamic_partition_control_android.cc
@@ -1200,22 +1200,32 @@
 }
 
 bool DynamicPartitionControlAndroid::ListDynamicPartitionsForSlot(
-    uint32_t current_slot, std::vector<std::string>* partitions) {
-  if (!GetDynamicPartitionsFeatureFlag().IsEnabled()) {
-    LOG(ERROR) << "Dynamic partition is not enabled";
-    return false;
+    uint32_t slot,
+    uint32_t current_slot,
+    std::vector<std::string>* partitions) {
+  bool slot_enables_dynamic_partitions =
+      GetDynamicPartitionsFeatureFlag().IsEnabled();
+  // Check if the target slot has dynamic partitions, this may happen when
+  // applying a retrofit package.
+  if (slot != current_slot) {
+    slot_enables_dynamic_partitions =
+        slot_enables_dynamic_partitions && is_target_dynamic_;
+  }
+
+  if (!slot_enables_dynamic_partitions) {
+    LOG(INFO) << "Dynamic partition is not enabled for slot " << slot;
+    return true;
   }
 
   std::string device_dir_str;
   TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
   base::FilePath device_dir(device_dir_str);
-  auto super_device =
-      device_dir.Append(GetSuperPartitionName(current_slot)).value();
-  auto builder = LoadMetadataBuilder(super_device, current_slot);
+  auto super_device = device_dir.Append(GetSuperPartitionName(slot)).value();
+  auto builder = LoadMetadataBuilder(super_device, slot);
   TEST_AND_RETURN_FALSE(builder != nullptr);
 
   std::vector<std::string> result;
-  auto suffix = SlotSuffixForSlotNumber(current_slot);
+  auto suffix = SlotSuffixForSlotNumber(slot);
   for (const auto& group : builder->ListGroups()) {
     for (const auto& partition : builder->ListPartitionsInGroup(group)) {
       std::string_view partition_name = partition->name();
@@ -1332,7 +1342,9 @@
     const std::string& partition_name) {
   if (dynamic_partition_list_.empty() &&
       GetDynamicPartitionsFeatureFlag().IsEnabled()) {
-    CHECK(ListDynamicPartitionsForSlot(source_slot_, &dynamic_partition_list_));
+    // Use the DAP config of the target slot.
+    CHECK(ListDynamicPartitionsForSlot(
+        target_slot_, source_slot_, &dynamic_partition_list_));
   }
   return std::find(dynamic_partition_list_.begin(),
                    dynamic_partition_list_.end(),
diff --git a/aosp/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h
index a0d7f30..d7c8781 100644
--- a/aosp/dynamic_partition_control_android.h
+++ b/aosp/dynamic_partition_control_android.h
@@ -58,7 +58,9 @@
   bool ResetUpdate(PrefsInterface* prefs) override;
 
   bool ListDynamicPartitionsForSlot(
-      uint32_t current_slot, std::vector<std::string>* partitions) override;
+      uint32_t slot,
+      uint32_t current_slot,
+      std::vector<std::string>* partitions) override;
 
   bool VerifyExtentsForUntouchedPartitions(
       uint32_t source_slot,
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 8368eeb..61127d4 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -134,11 +134,13 @@
   // allocated space for snapshot updates.
   virtual bool ResetUpdate(PrefsInterface* prefs) = 0;
 
-  // Reads the dynamic partitions metadata from the current slot, and puts the
+  // Reads the dynamic partitions metadata from the given slot, and puts the
   // name of the dynamic partitions with the current suffix to |partitions|.
   // Returns true on success.
   virtual bool ListDynamicPartitionsForSlot(
-      uint32_t current_slot, std::vector<std::string>* partitions) = 0;
+      uint32_t slot,
+      uint32_t current_slot,
+      std::vector<std::string>* partitions) = 0;
 
   // Finds a possible location that list all block devices by name; and puts
   // the result in |path|. Returns true on success.
diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc
index b6eff84..7d0ef18 100644
--- a/common/dynamic_partition_control_stub.cc
+++ b/common/dynamic_partition_control_stub.cc
@@ -73,7 +73,9 @@
 }
 
 bool DynamicPartitionControlStub::ListDynamicPartitionsForSlot(
-    uint32_t current_slot, std::vector<std::string>* partitions) {
+    uint32_t slot,
+    uint32_t current_slot,
+    std::vector<std::string>* partitions) {
   return true;
 }
 
diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h
index 822fa1b..5ab82f5 100644
--- a/common/dynamic_partition_control_stub.h
+++ b/common/dynamic_partition_control_stub.h
@@ -50,7 +50,9 @@
   bool ResetUpdate(PrefsInterface* prefs) override;
 
   bool ListDynamicPartitionsForSlot(
-      uint32_t current_slot, std::vector<std::string>* partitions) override;
+      uint32_t slot,
+      uint32_t current_slot,
+      std::vector<std::string>* partitions) override;
   bool GetDeviceDir(std::string* path) override;
 
   bool VerifyExtentsForUntouchedPartitions(
diff --git a/common/mock_dynamic_partition_control.h b/common/mock_dynamic_partition_control.h
index a00ec61..74f4efc 100644
--- a/common/mock_dynamic_partition_control.h
+++ b/common/mock_dynamic_partition_control.h
@@ -72,8 +72,9 @@
               (override));
   MOCK_METHOD(bool,
               ListDynamicPartitionsForSlot,
-              (uint32_t, std::vector<std::string>*),
+              (uint32_t, uint32_t, std::vector<std::string>*),
               (override));
+
   MOCK_METHOD(bool,
               VerifyExtentsForUntouchedPartitions,
               (uint32_t, uint32_t, const std::vector<std::string>&),
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index b06d04e..3df162e 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -644,11 +644,6 @@
     }
   }
 
-  auto dynamic_control = boot_control_->GetDynamicPartitionControl();
-  CHECK_NE(dynamic_control, nullptr);
-  TEST_AND_RETURN_FALSE(dynamic_control->ListDynamicPartitionsForSlot(
-      install_plan_->target_slot, &dynamic_partitions_));
-
   // Partitions in manifest are no longer needed after preparing partitions.
   manifest_.clear_partitions();
   // TODO(xunchang) TBD: allow partial update only on devices with dynamic
@@ -676,6 +671,7 @@
     std::vector<std::string> dynamic_partitions;
     if (!boot_control_->GetDynamicPartitionControl()
              ->ListDynamicPartitionsForSlot(install_plan_->source_slot,
+                                            boot_control_->GetCurrentSlot(),
                                             &dynamic_partitions)) {
       LOG(ERROR) << "Failed to load dynamic partitions from slot "
                  << install_plan_->source_slot;
@@ -1527,9 +1523,8 @@
 }
 
 bool DeltaPerformer::IsDynamicPartition(const std::string& part_name) {
-  return std::find(dynamic_partitions_.begin(),
-                   dynamic_partitions_.end(),
-                   part_name) != dynamic_partitions_.end();
+  return boot_control_->GetDynamicPartitionControl()->IsDynamicPartition(
+      part_name);
 }
 
 std::unique_ptr<PartitionWriter> DeltaPerformer::CreatePartitionWriter(
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index ec23997..31fa6b2 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -436,8 +436,6 @@
 
   std::unique_ptr<PartitionWriter> partition_writer_;
 
-  // List of dynamic partitions on device.
-  std::vector<std::string> dynamic_partitions_;
   DISALLOW_COPY_AND_ASSIGN(DeltaPerformer);
 };
 
diff --git a/payload_consumer/filesystem_verifier_action_unittest.cc b/payload_consumer/filesystem_verifier_action_unittest.cc
index e9560f0..658ebe1 100644
--- a/payload_consumer/filesystem_verifier_action_unittest.cc
+++ b/payload_consumer/filesystem_verifier_action_unittest.cc
@@ -426,9 +426,9 @@
       .Times(AtLeast(1));
   EXPECT_CALL(dynamic_control, OpenCowReader(part.name, {part.source_path}, _))
       .Times(1);
-  EXPECT_CALL(dynamic_control, ListDynamicPartitionsForSlot(_, _))
+  EXPECT_CALL(dynamic_control, ListDynamicPartitionsForSlot(_, _, _))
       .WillRepeatedly(
-          DoAll(SetArgPointee<1, std::vector<std::string>>({part.name}),
+          DoAll(SetArgPointee<2, std::vector<std::string>>({part.name}),
                 Return(true)));
 
   BuildActions(install_plan, &dynamic_control);