init: Look for super partition only on a boot device

Init code is bailing out as soon as `super` partition was
found in the system, ignoring rest of uevents.

In case given device contains multiple boot sources, `super`
partition as well as all other partitions shall be taken
from the same boot source, instead of relying on
`which uevent came first`.

Bug: 309244873, 349144493
Test: Plug secondary USB boot device to device that supports multiple
      boot sources. Select boot from USB. Device boots properly.

Signed-off-by: Jan Dabros <dabros@google.com>
Signed-off-by: Konrad Adamczyk <konrada@google.com>

Change-Id: I70eb7d4223258ec273faa523cb67ddab0b7c32a0
diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp
index 8f52158..cabeb01 100644
--- a/init/block_dev_initializer.cpp
+++ b/init/block_dev_initializer.cpp
@@ -98,7 +98,11 @@
 
     LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;
 
-    devices->erase(iter);
+    // Remove partition from the list only if it was found on boot device
+    if (device_handler_->IsBootDevice(uevent)) {
+        devices->erase(iter);
+    }
+
     device_handler_->HandleUevent(uevent);
     return devices->empty() ? ListenerAction::kStop : ListenerAction::kContinue;
 }
diff --git a/init/devices.cpp b/init/devices.cpp
index f2bb9d2..6a3a64d 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -188,6 +188,28 @@
     }
 }
 
+bool DeviceHandler::IsBootDevice(const Uevent& uevent) const {
+    std::string device;
+
+    if (FindPlatformDevice(uevent.path, &device)) {
+        // Skip /devices/platform or /devices/ if present
+        static constexpr std::string_view devices_platform_prefix = "/devices/platform/";
+        static constexpr std::string_view devices_prefix = "/devices/";
+
+        if (StartsWith(device, devices_platform_prefix)) {
+            device = device.substr(devices_platform_prefix.length());
+        } else if (StartsWith(device, devices_prefix)) {
+            device = device.substr(devices_prefix.length());
+        }
+    } else if (FindPciDevicePrefix(uevent.path, &device)) {
+    } else if (FindVbdDevicePrefix(uevent.path, &device)) {
+    } else {
+        return false;
+    }
+
+    return boot_devices_.find(device) != boot_devices_.end();
+}
+
 std::string DeviceHandler::GetPartitionNameForDevice(const std::string& query_device) {
     static const auto partition_map = [] {
         std::vector<std::pair<std::string, std::string>> partition_map;
diff --git a/init/devices.h b/init/devices.h
index 6da1232..4df604d 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -133,6 +133,7 @@
     // `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
     // `userdata`.
     static std::string GetPartitionNameForDevice(const std::string& device);
+    bool IsBootDevice(const Uevent& uevent) const;
 
   private:
     void ColdbootDone() override;