Merge "Add a fastboot command to show GSI status" into main
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index f76afba..d7e3db6 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -350,23 +350,22 @@
 //
 // The returned Transport is a singleton, so multiple calls to this function will return the same
 // object, and the caller should not attempt to delete the returned Transport.
-static Transport* open_device(const char* local_serial, bool wait_for_device = true,
-                              bool announce = true) {
+static std::unique_ptr<Transport> open_device(const char* local_serial,
+                                              bool wait_for_device = true,
+                                              bool announce = true) {
     const Result<NetworkSerial, FastbootError> network_serial = ParseNetworkSerial(local_serial);
 
-    Transport* transport = nullptr;
+    std::unique_ptr<Transport> transport;
     while (true) {
         if (network_serial.ok()) {
             std::string error;
             if (network_serial->protocol == Socket::Protocol::kTcp) {
-                transport = tcp::Connect(network_serial->address, network_serial->port, &error)
-                                    .release();
+                transport = tcp::Connect(network_serial->address, network_serial->port, &error);
             } else if (network_serial->protocol == Socket::Protocol::kUdp) {
-                transport = udp::Connect(network_serial->address, network_serial->port, &error)
-                                    .release();
+                transport = udp::Connect(network_serial->address, network_serial->port, &error);
             }
 
-            if (transport == nullptr && announce) {
+            if (!transport && announce) {
                 LOG(ERROR) << "error: " << error;
             }
         } else if (network_serial.error().code() ==
@@ -378,12 +377,12 @@
             Expect(network_serial);
         }
 
-        if (transport != nullptr) {
+        if (transport) {
             return transport;
         }
 
         if (!wait_for_device) {
-            return nullptr;
+            return transport;
         }
 
         if (announce) {
@@ -394,9 +393,9 @@
     }
 }
 
-static Transport* NetworkDeviceConnected(bool print = false) {
-    Transport* transport = nullptr;
-    Transport* result = nullptr;
+static std::unique_ptr<Transport> NetworkDeviceConnected(bool print = false) {
+    std::unique_ptr<Transport> transport;
+    std::unique_ptr<Transport> result;
 
     ConnectedDevicesStorage storage;
     std::set<std::string> devices;
@@ -409,11 +408,11 @@
         transport = open_device(device.c_str(), false, false);
 
         if (print) {
-            PrintDevice(device.c_str(), transport == nullptr ? "offline" : "fastboot");
+            PrintDevice(device.c_str(), transport ? "offline" : "fastboot");
         }
 
-        if (transport != nullptr) {
-            result = transport;
+        if (transport) {
+            result = std::move(transport);
         }
     }
 
@@ -431,21 +430,21 @@
 //
 // The returned Transport is a singleton, so multiple calls to this function will return the same
 // object, and the caller should not attempt to delete the returned Transport.
-static Transport* open_device() {
+static std::unique_ptr<Transport> open_device() {
     if (serial != nullptr) {
         return open_device(serial);
     }
 
     bool announce = true;
-    Transport* transport = nullptr;
+    std::unique_ptr<Transport> transport;
     while (true) {
         transport = usb_open(match_fastboot(nullptr));
-        if (transport != nullptr) {
+        if (transport) {
             return transport;
         }
 
         transport = NetworkDeviceConnected();
-        if (transport != nullptr) {
+        if (transport) {
             return transport;
         }
 
@@ -455,6 +454,8 @@
         }
         std::this_thread::sleep_for(std::chrono::seconds(1));
     }
+
+    return transport;
 }
 
 static int Connect(int argc, char* argv[]) {
@@ -466,8 +467,7 @@
     const char* local_serial = *argv;
     Expect(ParseNetworkSerial(local_serial));
 
-    const Transport* transport = open_device(local_serial, false);
-    if (transport == nullptr) {
+    if (!open_device(local_serial, false)) {
         return 1;
     }
 
@@ -531,6 +531,7 @@
     usb_open(list_devices_callback);
     NetworkDeviceConnected(/* print */ true);
 }
+
 void syntax_error(const char* fmt, ...) {
     fprintf(stderr, "fastboot: usage: ");
 
@@ -1547,9 +1548,7 @@
 
 void reboot_to_userspace_fastboot() {
     fb->RebootTo("fastboot");
-
-    auto* old_transport = fb->set_transport(nullptr);
-    delete old_transport;
+    fb->set_transport(nullptr);
 
     // Give the current connection time to close.
     std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -1678,7 +1677,7 @@
     }
     for (size_t i = 0; i < tasks->size(); i++) {
         if (auto flash_task = tasks->at(i)->AsFlashTask()) {
-            if (should_flash_in_userspace(*metadata.get(), flash_task->GetPartitionAndSlot())) {
+            if (FlashTask::IsDynamicParitition(fp->source, flash_task)) {
                 if (!loc) {
                     loc = i;
                 }
@@ -1760,25 +1759,15 @@
         }
         tasks.emplace_back(std::move(task));
     }
-    if (auto flash_super_task = OptimizedFlashSuperTask::InitializeFromTasks(fp, tasks)) {
-        auto it = tasks.begin();
-        for (size_t i = 0; i < tasks.size(); i++) {
-            if (auto flash_task = tasks[i]->AsFlashTask()) {
-                if (should_flash_in_userspace(flash_task->GetPartitionAndSlot())) {
-                    break;
-                }
-            }
-            if (auto wipe_task = tasks[i]->AsWipeTask()) {
-                break;
-            }
-            it++;
-        }
-        tasks.insert(it, std::move(flash_super_task));
+
+    if (auto flash_super_task = OptimizedFlashSuperTask::Initialize(fp, tasks)) {
+        tasks.emplace_back(std::move(flash_super_task));
     } else {
         if (!AddResizeTasks(fp, &tasks)) {
             LOG(WARNING) << "Failed to add resize tasks";
-        };
+        }
     }
+
     return tasks;
 }
 
@@ -1885,30 +1874,35 @@
     // or in bootloader fastboot.
     std::vector<std::unique_ptr<Task>> tasks;
     AddFlashTasks(boot_images_, tasks);
-    if (auto flash_super_task = OptimizedFlashSuperTask::Initialize(fp_, os_images_)) {
-        tasks.emplace_back(std::move(flash_super_task));
-    } else {
-        // Sync the super partition. This will reboot to userspace fastboot if needed.
-        tasks.emplace_back(std::make_unique<UpdateSuperTask>(fp_));
-        // Resize any logical partition to 0, so each partition is reset to 0
-        // extents, and will achieve more optimal allocation.
-        for (const auto& [image, slot] : os_images_) {
-            // Retrofit devices have two super partitions, named super_a and super_b.
-            // On these devices, secondary slots must be flashed as physical
-            // partitions (otherwise they would not mount on first boot). To enforce
-            // this, we delete any logical partitions for the "other" slot.
-            if (is_retrofit_device(fp_->fb)) {
-                std::string partition_name = image->part_name + "_"s + slot;
-                if (image->IsSecondary() && should_flash_in_userspace(partition_name)) {
-                    fp_->fb->DeletePartition(partition_name);
-                }
-                tasks.emplace_back(std::make_unique<DeleteTask>(fp_, partition_name));
+
+    // Sync the super partition. This will reboot to userspace fastboot if needed.
+    tasks.emplace_back(std::make_unique<UpdateSuperTask>(fp_));
+    for (const auto& [image, slot] : os_images_) {
+        // Retrofit devices have two super partitions, named super_a and super_b.
+        // On these devices, secondary slots must be flashed as physical
+        // partitions (otherwise they would not mount on first boot). To enforce
+        // this, we delete any logical partitions for the "other" slot.
+        if (is_retrofit_device(fp_->fb)) {
+            std::string partition_name = image->part_name + "_"s + slot;
+            if (image->IsSecondary() && should_flash_in_userspace(partition_name)) {
+                fp_->fb->DeletePartition(partition_name);
             }
-            tasks.emplace_back(std::make_unique<ResizeTask>(fp_, image->part_name, "0", slot));
+            tasks.emplace_back(std::make_unique<DeleteTask>(fp_, partition_name));
         }
     }
 
     AddFlashTasks(os_images_, tasks);
+
+    if (auto flash_super_task = OptimizedFlashSuperTask::Initialize(fp_, tasks)) {
+        tasks.emplace_back(std::move(flash_super_task));
+    } else {
+        // Resize any logical partition to 0, so each partition is reset to 0
+        // extents, and will achieve more optimal allocation.
+        if (!AddResizeTasks(fp_, &tasks)) {
+            LOG(WARNING) << "Failed to add resize tasks";
+        }
+    }
+
     return tasks;
 }
 
@@ -2377,8 +2371,8 @@
         return show_help();
     }
 
-    Transport* transport = open_device();
-    if (transport == nullptr) {
+    std::unique_ptr<Transport> transport = open_device();
+    if (!transport) {
         return 1;
     }
     fastboot::DriverCallbacks driver_callbacks = {
@@ -2388,7 +2382,7 @@
             .text = TextMessage,
     };
 
-    fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false);
+    fastboot::FastBootDriver fastboot_driver(std::move(transport), driver_callbacks, false);
     fb = &fastboot_driver;
     fp->fb = &fastboot_driver;
 
@@ -2631,9 +2625,6 @@
     }
     fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));
 
-    auto* old_transport = fb->set_transport(nullptr);
-    delete old_transport;
-
     return 0;
 }
 
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index 9770ab2..e5ef66b 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -58,9 +58,10 @@
 namespace fastboot {
 
 /*************************** PUBLIC *******************************/
-FastBootDriver::FastBootDriver(Transport* transport, DriverCallbacks driver_callbacks,
+FastBootDriver::FastBootDriver(std::unique_ptr<Transport> transport,
+                               DriverCallbacks driver_callbacks,
                                bool no_checks)
-    : transport_(transport),
+    : transport_(std::move(transport)),
       prolog_(std::move(driver_callbacks.prolog)),
       epilog_(std::move(driver_callbacks.epilog)),
       info_(std::move(driver_callbacks.info)),
@@ -627,9 +628,8 @@
     return 0;
 }
 
-Transport* FastBootDriver::set_transport(Transport* transport) {
-    std::swap(transport_, transport);
-    return transport;
+void FastBootDriver::set_transport(std::unique_ptr<Transport> transport) {
+    transport_ = std::move(transport);
 }
 
 }  // End namespace fastboot
diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h
index 8774ead..30298cb 100644
--- a/fastboot/fastboot_driver.h
+++ b/fastboot/fastboot_driver.h
@@ -30,6 +30,7 @@
 #include <deque>
 #include <functional>
 #include <limits>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -63,7 +64,7 @@
     static constexpr uint32_t MAX_DOWNLOAD_SIZE = std::numeric_limits<uint32_t>::max();
     static constexpr size_t TRANSPORT_CHUNK_SIZE = 1024;
 
-    FastBootDriver(Transport* transport, DriverCallbacks driver_callbacks = {},
+    FastBootDriver(std::unique_ptr<Transport> transport, DriverCallbacks driver_callbacks = {},
                    bool no_checks = false);
     ~FastBootDriver();
 
@@ -124,9 +125,7 @@
     std::string Error();
     RetCode WaitForDisconnect() override;
 
-    // Note: set_transport will return the previous transport.
-    Transport* set_transport(Transport* transport);
-    Transport* transport() const { return transport_; }
+    void set_transport(std::unique_ptr<Transport> transport);
 
     RetCode RawCommand(const std::string& cmd, const std::string& message,
                        std::string* response = nullptr, std::vector<std::string>* info = nullptr,
@@ -143,7 +142,7 @@
 
     std::string ErrnoStr(const std::string& msg);
 
-    Transport* transport_;
+    std::unique_ptr<Transport> transport_;
 
   private:
     RetCode SendBuffer(android::base::borrowed_fd fd, size_t size);
diff --git a/fastboot/fastboot_driver_test.cpp b/fastboot/fastboot_driver_test.cpp
index 6f6cf8c..d2033b0 100644
--- a/fastboot/fastboot_driver_test.cpp
+++ b/fastboot/fastboot_driver_test.cpp
@@ -16,6 +16,7 @@
 
 #include "fastboot_driver.h"
 
+#include <memory>
 #include <optional>
 
 #include <gtest/gtest.h>
@@ -30,13 +31,14 @@
 };
 
 TEST_F(DriverTest, GetVar) {
-    MockTransport transport;
-    FastBootDriver driver(&transport);
+    std::unique_ptr<MockTransport> transport_pointer = std::make_unique<MockTransport>();
+    MockTransport* transport = transport_pointer.get();
+    FastBootDriver driver(std::move(transport_pointer));
 
-    EXPECT_CALL(transport, Write(_, _))
+    EXPECT_CALL(*transport, Write(_, _))
             .With(AllArgs(RawData("getvar:version")))
             .WillOnce(ReturnArg<1>());
-    EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY0.4")));
+    EXPECT_CALL(*transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY0.4")));
 
     std::string output;
     ASSERT_EQ(driver.GetVar("version", &output), SUCCESS) << driver.Error();
@@ -44,14 +46,15 @@
 }
 
 TEST_F(DriverTest, InfoMessage) {
-    MockTransport transport;
-    FastBootDriver driver(&transport);
+    std::unique_ptr<MockTransport> transport_pointer = std::make_unique<MockTransport>();
+    MockTransport* transport = transport_pointer.get();
+    FastBootDriver driver(std::move(transport_pointer));
 
-    EXPECT_CALL(transport, Write(_, _))
+    EXPECT_CALL(*transport, Write(_, _))
             .With(AllArgs(RawData("oem dmesg")))
             .WillOnce(ReturnArg<1>());
-    EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("INFOthis is an info line")));
-    EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
+    EXPECT_CALL(*transport, Read(_, _)).WillOnce(Invoke(CopyData("INFOthis is an info line")));
+    EXPECT_CALL(*transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
 
     std::vector<std::string> info;
     ASSERT_EQ(driver.RawCommand("oem dmesg", "", nullptr, &info), SUCCESS) << driver.Error();
@@ -60,28 +63,29 @@
 }
 
 TEST_F(DriverTest, TextMessage) {
-    MockTransport transport;
     std::string text;
+    std::unique_ptr<MockTransport> transport_pointer = std::make_unique<MockTransport>();
+    MockTransport* transport = transport_pointer.get();
 
     DriverCallbacks callbacks{[](const std::string&) {}, [](int) {}, [](const std::string&) {},
                               [&text](const std::string& extra_text) { text += extra_text; }};
 
-    FastBootDriver driver(&transport, callbacks);
+    FastBootDriver driver(std::move(transport_pointer), callbacks);
 
-    EXPECT_CALL(transport, Write(_, _))
+    EXPECT_CALL(*transport, Write(_, _))
             .With(AllArgs(RawData("oem trusty runtest trusty.hwaes.bench")))
             .WillOnce(ReturnArg<1>());
-    EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("TEXTthis is a text line")));
-    EXPECT_CALL(transport, Read(_, _))
+    EXPECT_CALL(*transport, Read(_, _)).WillOnce(Invoke(CopyData("TEXTthis is a text line")));
+    EXPECT_CALL(*transport, Read(_, _))
             .WillOnce(Invoke(
                     CopyData("TEXT, albeit very long and split over multiple TEXT messages.")));
-    EXPECT_CALL(transport, Read(_, _))
+    EXPECT_CALL(*transport, Read(_, _))
             .WillOnce(Invoke(CopyData("TEXT Indeed we can do that now with a TEXT message whenever "
                                       "we feel like it.")));
-    EXPECT_CALL(transport, Read(_, _))
+    EXPECT_CALL(*transport, Read(_, _))
             .WillOnce(Invoke(CopyData("TEXT Isn't that truly super cool?")));
 
-    EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
+    EXPECT_CALL(*transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
 
     std::vector<std::string> info;
     ASSERT_EQ(driver.RawCommand("oem trusty runtest trusty.hwaes.bench", "", nullptr, &info),
diff --git a/fastboot/fuzzy_fastboot/fixtures.cpp b/fastboot/fuzzy_fastboot/fixtures.cpp
index 9b5e5f7..94a53ed 100644
--- a/fastboot/fuzzy_fastboot/fixtures.cpp
+++ b/fastboot/fuzzy_fastboot/fixtures.cpp
@@ -128,7 +128,7 @@
             return MatchFastboot(info, device_serial);
         };
         for (int i = 0; i < MAX_USB_TRIES && !transport; i++) {
-            std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
+            std::unique_ptr<UsbTransport> usb = usb_open(matcher, USB_TIMEOUT);
             if (usb)
                 transport = std::unique_ptr<TransportSniffer>(
                         new TransportSniffer(std::move(usb), serial_port));
@@ -143,7 +143,7 @@
     } else {
         ASSERT_EQ(device_path, cb_scratch);  // The path can not change
     }
-    fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+    fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(std::move(transport), {}, true));
     // No error checking since non-A/B devices may not support the command
     fb->GetVar("current-slot", &initial_slot);
 }
@@ -200,7 +200,7 @@
     if (IsFastbootOverTcp()) {
         ConnectTcpFastbootDevice();
         device_path = cb_scratch;
-        fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+        fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(std::move(transport), {}, true));
         return;
     }
 
@@ -212,7 +212,7 @@
         return MatchFastboot(info, device_serial);
     };
     while (!transport) {
-        std::unique_ptr<UsbTransport> usb(usb_open(matcher, USB_TIMEOUT));
+        std::unique_ptr<UsbTransport> usb = usb_open(matcher, USB_TIMEOUT);
         if (usb) {
             transport = std::unique_ptr<TransportSniffer>(
                     new TransportSniffer(std::move(usb), serial_port));
@@ -220,7 +220,7 @@
         std::this_thread::sleep_for(1s);
     }
     device_path = cb_scratch;
-    fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+    fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(std::move(transport), {}, true));
 }
 
 void FastBootTest::SetLockState(bool unlock, bool assert_change) {
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index e635937..43aaec9 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -166,16 +166,15 @@
     const auto matcher = [](usb_ifc_info* info) -> int {
         return FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
     };
-    Transport* transport = nullptr;
+    std::unique_ptr<Transport> transport;
     for (int i = 0; i < FastBootTest::MAX_USB_TRIES && !transport; i++) {
         transport = usb_open(matcher);
         std::this_thread::sleep_for(std::chrono::milliseconds(10));
     }
-    ASSERT_NE(transport, nullptr) << "Could not find the fastboot device after: "
-                                  << 10 * FastBootTest::MAX_USB_TRIES << "ms";
+    ASSERT_NE(transport.get(), nullptr) << "Could not find the fastboot device after: "
+                                        << 10 * FastBootTest::MAX_USB_TRIES << "ms";
     if (transport) {
         transport->Close();
-        delete transport;
     }
 }
 
@@ -1897,7 +1896,7 @@
         const auto matcher = [](usb_ifc_info* info) -> int {
             return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
         };
-        Transport* transport = nullptr;
+        std::unique_ptr<Transport> transport;
         while (!transport) {
             transport = usb_open(matcher);
             std::this_thread::sleep_for(std::chrono::milliseconds(10));
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index 146064c..f0eed0c 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -15,6 +15,7 @@
 //
 #include "task.h"
 
+#include <cstddef>
 #include <iostream>
 
 #include <android-base/logging.h>
@@ -30,6 +31,15 @@
                      const bool apply_vbmeta, const FlashingPlan* fp)
     : pname_(pname), fname_(fname), slot_(slot), apply_vbmeta_(apply_vbmeta), fp_(fp) {}
 
+bool FlashTask::IsDynamicParitition(const ImageSource* source, const FlashTask* task) {
+    std::vector<char> contents;
+    if (!source->ReadFile("super_empty.img", &contents)) {
+        return false;
+    }
+    auto metadata = android::fs_mgr::ReadFromImageBlob(contents.data(), contents.size());
+    return should_flash_in_userspace(*metadata.get(), task->GetPartitionAndSlot());
+}
+
 void FlashTask::Run() {
     auto flash = [&](const std::string& partition) {
         if (should_flash_in_userspace(partition) && !is_userspace_fastboot() && !fp_->force_flash) {
@@ -46,7 +56,7 @@
     do_for_partitions(pname_, slot_, flash, true);
 }
 
-std::string FlashTask::ToString() {
+std::string FlashTask::ToString() const {
     std::string apply_vbmeta_string = "";
     if (apply_vbmeta_) {
         apply_vbmeta_string = " --apply_vbmeta";
@@ -54,7 +64,7 @@
     return "flash" + apply_vbmeta_string + " " + pname_ + " " + fname_;
 }
 
-std::string FlashTask::GetPartitionAndSlot() {
+std::string FlashTask::GetPartitionAndSlot() const {
     auto slot = slot_;
     if (slot.empty()) {
         slot = get_current_slot();
@@ -92,7 +102,7 @@
     }
 }
 
-std::string RebootTask::ToString() {
+std::string RebootTask::ToString() const {
     return "reboot " + reboot_target_;
 }
 
@@ -120,79 +130,36 @@
     // Send the data to the device.
     flash_partition_files(super_name_, files);
 }
-std::string OptimizedFlashSuperTask::ToString() {
+std::string OptimizedFlashSuperTask::ToString() const {
     return "optimized-flash-super";
 }
 
-std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::Initialize(
-        const FlashingPlan* fp, std::vector<ImageEntry>& os_images) {
-    if (!fp->should_optimize_flash_super) {
-        LOG(INFO) << "super optimization is disabled";
-        return nullptr;
-    }
-    if (!supports_AB()) {
-        LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
-        return nullptr;
-    }
-    if (fp->slot_override == "all") {
-        LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
-        return nullptr;
-    }
-
-    // Does this device use dynamic partitions at all?
-    unique_fd fd = fp->source->OpenFile("super_empty.img");
-
-    if (fd < 0) {
-        LOG(VERBOSE) << "could not open super_empty.img";
-        return nullptr;
-    }
-
-    std::string super_name;
-    // Try to find whether there is a super partition.
-    if (fp->fb->GetVar("super-partition-name", &super_name) != fastboot::SUCCESS) {
-        super_name = "super";
-    }
-
-    uint64_t partition_size;
-    std::string partition_size_str;
-    if (fp->fb->GetVar("partition-size:" + super_name, &partition_size_str) != fastboot::SUCCESS) {
-        LOG(VERBOSE) << "Cannot optimize super flashing: could not determine super partition";
-        return nullptr;
-    }
-    partition_size_str = fb_fix_numeric_var(partition_size_str);
-    if (!android::base::ParseUint(partition_size_str, &partition_size)) {
-        LOG(VERBOSE) << "Could not parse " << super_name << " size: " << partition_size_str;
-        return nullptr;
-    }
-
-    std::unique_ptr<SuperFlashHelper> helper = std::make_unique<SuperFlashHelper>(*fp->source);
-    if (!helper->Open(fd)) {
-        return nullptr;
-    }
-
-    for (const auto& entry : os_images) {
-        auto partition = GetPartitionName(entry, fp->current_slot);
-        auto image = entry.first;
-
-        if (!helper->AddPartition(partition, image->img_name, image->optional_if_no_image)) {
-            return nullptr;
+// This looks for a block within tasks that has the following pattern [reboot fastboot,
+// update-super, $LIST_OF_DYNAMIC_FLASH_TASKS] and returns true if this is found.Theoretically
+// this check is just a pattern match and could break if fastboot-info has a bunch of junk commands
+// but all devices should pretty much follow this pattern
+bool OptimizedFlashSuperTask::CanOptimize(const ImageSource* source,
+                                          const std::vector<std::unique_ptr<Task>>& tasks) {
+    for (size_t i = 0; i < tasks.size(); i++) {
+        auto reboot_task = tasks[i]->AsRebootTask();
+        if (!reboot_task || reboot_task->GetTarget() != "fastboot") {
+            continue;
         }
+        // The check for i >= tasks.size() - 2 is because we are peeking two tasks ahead. We need to
+        // check for an update-super && flash {dynamic_partition}
+        if (i >= tasks.size() - 2 || !tasks[i + 1]->AsUpdateSuperTask()) {
+            continue;
+        }
+        auto flash_task = tasks[i + 2]->AsFlashTask();
+        if (!FlashTask::IsDynamicParitition(source, flash_task)) {
+            continue;
+        }
+        return true;
     }
-
-    auto s = helper->GetSparseLayout();
-    if (!s) return nullptr;
-
-    // Remove images that we already flashed, just in case we have non-dynamic OS images.
-    auto remove_if_callback = [&](const ImageEntry& entry) -> bool {
-        return helper->WillFlash(GetPartitionName(entry, fp->current_slot));
-    };
-    os_images.erase(std::remove_if(os_images.begin(), os_images.end(), remove_if_callback),
-                    os_images.end());
-    return std::make_unique<OptimizedFlashSuperTask>(super_name, std::move(helper), std::move(s),
-                                                     partition_size, fp);
+    return false;
 }
 
-std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::InitializeFromTasks(
+std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::Initialize(
         const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks) {
     if (!fp->should_optimize_flash_super) {
         LOG(INFO) << "super optimization is disabled";
@@ -206,6 +173,9 @@
         LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
         return nullptr;
     }
+    if (!CanOptimize(fp->source, tasks)) {
+        return nullptr;
+    }
 
     // Does this device use dynamic partitions at all?
     unique_fd fd = fp->source->OpenFile("super_empty.img");
@@ -288,7 +258,7 @@
     }
     fp_->fb->RawCommand(command, "Updating super partition");
 }
-std::string UpdateSuperTask::ToString() {
+std::string UpdateSuperTask::ToString() const {
     return "update-super";
 }
 
@@ -305,7 +275,7 @@
     do_for_partitions(pname_, slot_, resize_partition, false);
 }
 
-std::string ResizeTask::ToString() {
+std::string ResizeTask::ToString() const {
     return "resize " + pname_;
 }
 
@@ -315,7 +285,7 @@
     fp_->fb->DeletePartition(pname_);
 }
 
-std::string DeleteTask::ToString() {
+std::string DeleteTask::ToString() const {
     return "delete " + pname_;
 }
 
@@ -335,6 +305,6 @@
     fb_perform_format(pname_, 1, partition_type, "", fp_->fs_options, fp_);
 }
 
-std::string WipeTask::ToString() {
+std::string WipeTask::ToString() const {
     return "erase " + pname_;
 }
diff --git a/fastboot/task.h b/fastboot/task.h
index f7c8801..6ebe381 100644
--- a/fastboot/task.h
+++ b/fastboot/task.h
@@ -30,17 +30,18 @@
 class RebootTask;
 class UpdateSuperTask;
 class WipeTask;
-
+class ResizeTask;
 class Task {
   public:
     Task() = default;
     virtual void Run() = 0;
-    virtual std::string ToString() = 0;
+    virtual std::string ToString() const = 0;
 
     virtual FlashTask* AsFlashTask() { return nullptr; }
     virtual RebootTask* AsRebootTask() { return nullptr; }
     virtual UpdateSuperTask* AsUpdateSuperTask() { return nullptr; }
     virtual WipeTask* AsWipeTask() { return nullptr; }
+    virtual ResizeTask* AsResizeTask() { return nullptr; }
 
     virtual ~Task() = default;
 };
@@ -51,12 +52,13 @@
               const bool apply_vbmeta, const FlashingPlan* fp);
     virtual FlashTask* AsFlashTask() override { return this; }
 
+    static bool IsDynamicParitition(const ImageSource* source, const FlashTask* task);
     void Run() override;
-    std::string ToString() override;
-    std::string GetPartition() { return pname_; }
-    std::string GetImageName() { return fname_; }
-    std::string GetSlot() { return slot_; }
-    std::string GetPartitionAndSlot();
+    std::string ToString() const override;
+    std::string GetPartition() const { return pname_; }
+    std::string GetImageName() const { return fname_; }
+    std::string GetSlot() const { return slot_; }
+    std::string GetPartitionAndSlot() const;
 
   private:
     const std::string pname_;
@@ -72,7 +74,8 @@
     RebootTask(const FlashingPlan* fp, const std::string& reboot_target);
     virtual RebootTask* AsRebootTask() override { return this; }
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
+    std::string GetTarget() const { return reboot_target_; };
 
   private:
     const std::string reboot_target_ = "";
@@ -83,13 +86,15 @@
   public:
     OptimizedFlashSuperTask(const std::string& super_name, std::unique_ptr<SuperFlashHelper> helper,
                             SparsePtr sparse_layout, uint64_t super_size, const FlashingPlan* fp);
-    static std::unique_ptr<OptimizedFlashSuperTask> Initialize(const FlashingPlan* fp,
-                                                               std::vector<ImageEntry>& os_images);
-    static std::unique_ptr<OptimizedFlashSuperTask> InitializeFromTasks(
+
+    static std::unique_ptr<OptimizedFlashSuperTask> Initialize(
             const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks);
+    static bool CanOptimize(const ImageSource* source,
+                            const std::vector<std::unique_ptr<Task>>& tasks);
+
     using ImageEntry = std::pair<const Image*, std::string>;
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
 
   private:
     const std::string super_name_;
@@ -105,7 +110,7 @@
     virtual UpdateSuperTask* AsUpdateSuperTask() override { return this; }
 
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
 
   private:
     const FlashingPlan* fp_;
@@ -116,7 +121,8 @@
     ResizeTask(const FlashingPlan* fp, const std::string& pname, const std::string& size,
                const std::string& slot);
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
+    virtual ResizeTask* AsResizeTask() override { return this; }
 
   private:
     const FlashingPlan* fp_;
@@ -129,7 +135,7 @@
   public:
     DeleteTask(const FlashingPlan* fp, const std::string& pname);
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
 
   private:
     const FlashingPlan* fp_;
@@ -141,7 +147,7 @@
     WipeTask(const FlashingPlan* fp, const std::string& pname);
     virtual WipeTask* AsWipeTask() override { return this; }
     void Run() override;
-    std::string ToString() override;
+    std::string ToString() const override;
 
   private:
     const FlashingPlan* fp_;
diff --git a/fastboot/usb.h b/fastboot/usb.h
index 69581ab..d85cb81 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -29,6 +29,7 @@
 #pragma once
 
 #include <functional>
+#include <memory>
 
 #include "transport.h"
 
@@ -66,4 +67,4 @@
 typedef std::function<int(usb_ifc_info*)> ifc_match_func;
 
 // 0 is non blocking
-UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms = 0);
+std::unique_ptr<UsbTransport> usb_open(ifc_match_func callback, uint32_t timeout_ms = 0);
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 964488c..37bb304 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -503,9 +503,15 @@
     return 0;
 }
 
-UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) {
+std::unique_ptr<UsbTransport> usb_open(ifc_match_func callback, uint32_t timeout_ms) {
+    std::unique_ptr<UsbTransport> result;
     std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback);
-    return handle ? new LinuxUsbTransport(std::move(handle), timeout_ms) : nullptr;
+
+    if (handle) {
+        result = std::make_unique<LinuxUsbTransport>(std::move(handle), timeout_ms);
+    }
+
+    return result;
 }
 
 /* Wait for the system to notice the device is gone, so that a subsequent
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 8b852f5..28300b2 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -469,16 +469,20 @@
 /*
  * Definitions of this file's public functions.
  */
-
-UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) {
+std::unique_ptr<UsbTransport> usb_open(ifc_match_func callback, uint32_t timeout_ms) {
+    std::unique_ptr<UsbTransport> result;
     std::unique_ptr<usb_handle> handle;
 
     if (init_usb(callback, &handle) < 0) {
         /* Something went wrong initializing USB. */
-        return nullptr;
+        return result;
     }
 
-    return new OsxUsbTransport(std::move(handle), timeout_ms);
+    if (handle) {
+        result = std::make_unique<OsxUsbTransport>(std::move(handle), timeout_ms);
+    }
+
+    return result;
 }
 
 OsxUsbTransport::~OsxUsbTransport() {
diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp
index 67bf8a3..56a6e7d 100644
--- a/fastboot/usb_windows.cpp
+++ b/fastboot/usb_windows.cpp
@@ -381,7 +381,13 @@
     return handle;
 }
 
-UsbTransport* usb_open(ifc_match_func callback, uint32_t) {
+std::unique_ptr<UsbTransport> usb_open(ifc_match_func callback, uint32_t) {
+    std::unique_ptr<UsbTransport> result;
     std::unique_ptr<usb_handle> handle = find_usb_device(callback);
-    return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr;
+
+    if (handle) {
+        result = std::make_unique<WindowsUsbTransport>(std::move(handle));
+    }
+
+    return result;
 }
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index d357e45..1694969 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -28,6 +28,9 @@
     //{"name": "vabc_legacy_tests"},
     {
       "name": "cow_api_test"
+    },
+    {
+      "name": "snapuserd_test"
     }
   ],
   "kernel-presubmit": [
@@ -42,8 +45,11 @@
     },
     {
       "name": "vab_legacy_tests"
-    }
+    },
     // TODO: b/279009697
     //{"name": "vabc_legacy_tests"}
+    {
+      "name": "snapuserd_test"
+    }
   ]
 }
diff --git a/fs_mgr/libsnapshot/OWNERS b/fs_mgr/libsnapshot/OWNERS
index 1ee4175..c8b1003 100644
--- a/fs_mgr/libsnapshot/OWNERS
+++ b/fs_mgr/libsnapshot/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 30545
+# Bug component: 1014951
 balsini@google.com
 dvander@google.com
 elsk@google.com
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 6548cc8..e56ffbe 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -214,8 +214,8 @@
     require_root: false,
 }
 
-cc_test {
-    name: "snapuserd_test",
+cc_defaults {
+    name: "snapuserd_test_defaults",
     defaults: [
         "fs_mgr_defaults",
         "libsnapshot_cow_defaults",
@@ -256,5 +256,24 @@
         min_shipping_api_level: 30,
     },
     auto_gen_config: true,
-    require_root: false,
+    require_root: true,
+    compile_multilib: "first",
+}
+
+cc_test {
+    name: "snapuserd_test",
+    defaults: ["snapuserd_test_defaults"],
+    host_supported: true,
+    test_suites: [
+        "device-tests",
+    ],
+}
+
+// vts tests cannot be host_supported.
+cc_test {
+    name: "vts_snapuserd_test",
+    defaults: ["snapuserd_test_defaults"],
+    test_suites: [
+        "vts",
+    ],
 }
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_transitions.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_transitions.cpp
index 52e4f89..f3e0019 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_transitions.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_transitions.cpp
@@ -189,35 +189,32 @@
     cv.notify_all();
 }
 
+static inline bool IsMergeBeginError(MERGE_IO_TRANSITION io_state) {
+    return io_state == MERGE_IO_TRANSITION::READ_AHEAD_FAILURE ||
+           io_state == MERGE_IO_TRANSITION::IO_TERMINATED;
+}
+
 // Invoked by Merge thread - Waits on RA thread to resume merging. Will
 // be waken up RA thread.
 bool SnapshotHandler::WaitForMergeBegin() {
-    {
-        std::unique_lock<std::mutex> lock(lock_);
-        while (!MergeInitiated()) {
-            cv.wait(lock);
+    std::unique_lock<std::mutex> lock(lock_);
 
-            if (io_state_ == MERGE_IO_TRANSITION::READ_AHEAD_FAILURE ||
-                io_state_ == MERGE_IO_TRANSITION::IO_TERMINATED) {
-                SNAP_LOG(ERROR) << "WaitForMergeBegin failed with state: " << io_state_;
-                return false;
-            }
-        }
+    cv.wait(lock, [this]() -> bool { return MergeInitiated() || IsMergeBeginError(io_state_); });
 
-        while (!(io_state_ == MERGE_IO_TRANSITION::MERGE_BEGIN ||
-                 io_state_ == MERGE_IO_TRANSITION::READ_AHEAD_FAILURE ||
-                 io_state_ == MERGE_IO_TRANSITION::IO_TERMINATED)) {
-            cv.wait(lock);
-        }
-
-        if (io_state_ == MERGE_IO_TRANSITION::READ_AHEAD_FAILURE ||
-            io_state_ == MERGE_IO_TRANSITION::IO_TERMINATED) {
-            SNAP_LOG(ERROR) << "WaitForMergeBegin failed with state: " << io_state_;
-            return false;
-        }
-
-        return true;
+    if (IsMergeBeginError(io_state_)) {
+        SNAP_LOG(ERROR) << "WaitForMergeBegin failed with state: " << io_state_;
+        return false;
     }
+
+    cv.wait(lock, [this]() -> bool {
+        return io_state_ == MERGE_IO_TRANSITION::MERGE_BEGIN || IsMergeBeginError(io_state_);
+    });
+
+    if (IsMergeBeginError(io_state_)) {
+        SNAP_LOG(ERROR) << "WaitForMergeBegin failed with state: " << io_state_;
+        return false;
+    }
+    return true;
 }
 
 // Invoked by RA thread - Flushes the RA block to scratch space if necessary
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 15c30be..e4cf582 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -361,7 +361,7 @@
 void BatteryMonitor::updateValues(void) {
     initHealthInfo(mHealthInfo.get());
 
-    if (!mHealthdConfig->batteryPresentPath.isEmpty())
+    if (!mHealthdConfig->batteryPresentPath.empty())
         mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
     else
         mHealthInfo->batteryPresent = mBatteryDevicePresent;
@@ -371,43 +371,43 @@
                                         : getIntField(mHealthdConfig->batteryCapacityPath);
     mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
+    if (!mHealthdConfig->batteryCurrentNowPath.empty())
         mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
 
-    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
+    if (!mHealthdConfig->batteryFullChargePath.empty())
         mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
 
-    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
+    if (!mHealthdConfig->batteryCycleCountPath.empty())
         mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
 
-    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
+    if (!mHealthdConfig->batteryChargeCounterPath.empty())
         mHealthInfo->batteryChargeCounterUah =
                 getIntField(mHealthdConfig->batteryChargeCounterPath);
 
-    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())
+    if (!mHealthdConfig->batteryCurrentAvgPath.empty())
         mHealthInfo->batteryCurrentAverageMicroamps =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
 
-    if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+    if (!mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
         mHealthInfo->batteryChargeTimeToFullNowSeconds =
                 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
 
-    if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+    if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
         mHealthInfo->batteryFullChargeDesignCapacityUah =
                 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
 
-    if (!mHealthdConfig->batteryHealthStatusPath.isEmpty())
+    if (!mHealthdConfig->batteryHealthStatusPath.empty())
         mBatteryHealthStatus = getIntField(mHealthdConfig->batteryHealthStatusPath);
 
-    if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+    if (!mHealthdConfig->batteryStateOfHealthPath.empty())
         mHealthInfo->batteryHealthData->batteryStateOfHealth =
                 getIntField(mHealthdConfig->batteryStateOfHealthPath);
 
-    if (!mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+    if (!mHealthdConfig->batteryManufacturingDatePath.empty())
         mHealthInfo->batteryHealthData->batteryManufacturingDateSeconds =
                 getIntField(mHealthdConfig->batteryManufacturingDatePath);
 
-    if (!mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+    if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
         mHealthInfo->batteryHealthData->batteryFirstUsageSeconds =
                 getIntField(mHealthdConfig->batteryFirstUsageDatePath);
 
@@ -506,17 +506,17 @@
                  props.batteryStatus);
 
         len = strlen(dmesgline);
-        if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
+        if (!healthd_config.batteryCurrentNowPath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
                             props.batteryCurrentMicroamps);
         }
 
-        if (!healthd_config.batteryFullChargePath.isEmpty()) {
+        if (!healthd_config.batteryFullChargePath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
                             props.batteryFullChargeUah);
         }
 
-        if (!healthd_config.batteryCycleCountPath.isEmpty()) {
+        if (!healthd_config.batteryCycleCountPath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
                             props.batteryCycleCount);
         }
@@ -550,7 +550,7 @@
 
 int BatteryMonitor::getChargeStatus() {
     BatteryStatus result = BatteryStatus::UNKNOWN;
-    if (!mHealthdConfig->batteryStatusPath.isEmpty()) {
+    if (!mHealthdConfig->batteryStatusPath.empty()) {
         std::string buf;
         if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
             result = getBatteryStatus(buf.c_str());
@@ -561,7 +561,7 @@
 status_t BatteryMonitor::setChargingPolicy(int value) {
     status_t ret = NAME_NOT_FOUND;
     bool result;
-    if (!mHealthdConfig->chargingPolicyPath.isEmpty()) {
+    if (!mHealthdConfig->chargingPolicyPath.empty()) {
         result = writeToFile(mHealthdConfig->chargingPolicyPath, value);
         if (!result) {
             KLOG_WARNING(LOG_TAG, "setChargingPolicy fail\n");
@@ -575,7 +575,7 @@
 
 int BatteryMonitor::getChargingPolicy() {
     BatteryChargingPolicy result = BatteryChargingPolicy::DEFAULT;
-    if (!mHealthdConfig->chargingPolicyPath.isEmpty()) {
+    if (!mHealthdConfig->chargingPolicyPath.empty()) {
         std::string buf;
         if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
             result = getBatteryChargingPolicy(buf.c_str());
@@ -585,15 +585,15 @@
 
 int BatteryMonitor::getBatteryHealthData(int id) {
     if (id == BATTERY_PROP_MANUFACTURING_DATE) {
-        if (!mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+        if (!mHealthdConfig->batteryManufacturingDatePath.empty())
             return getIntField(mHealthdConfig->batteryManufacturingDatePath);
     }
     if (id == BATTERY_PROP_FIRST_USAGE_DATE) {
-        if (!mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+        if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
             return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
     }
     if (id == BATTERY_PROP_STATE_OF_HEALTH) {
-        if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+        if (!mHealthdConfig->batteryStateOfHealthPath.empty())
             return getIntField(mHealthdConfig->batteryStateOfHealthPath);
     }
     return 0;
@@ -607,7 +607,7 @@
 
     switch(id) {
     case BATTERY_PROP_CHARGE_COUNTER:
-        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+        if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryChargeCounterPath);
             ret = OK;
@@ -617,7 +617,7 @@
         break;
 
     case BATTERY_PROP_CURRENT_NOW:
-        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentNowPath);
             ret = OK;
@@ -627,7 +627,7 @@
         break;
 
     case BATTERY_PROP_CURRENT_AVG:
-        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
             ret = OK;
@@ -637,7 +637,7 @@
         break;
 
     case BATTERY_PROP_CAPACITY:
-        if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCapacityPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCapacityPath);
             ret = OK;
@@ -704,35 +704,35 @@
              props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
     write(fd, vs, strlen(vs));
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
         v = getIntField(mHealthdConfig->batteryCurrentNowPath);
         snprintf(vs, sizeof(vs), "current now: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
         v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
         snprintf(vs, sizeof(vs), "current avg: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+    if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
         v = getIntField(mHealthdConfig->batteryChargeCounterPath);
         snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
         snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCycleCountPath.empty()) {
         snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
+    if (!mHealthdConfig->batteryFullChargePath.empty()) {
         snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
         write(fd, vs, strlen(vs));
     }
@@ -782,7 +782,7 @@
                 if (isScopedPowerSupply(name)) continue;
                 mBatteryDevicePresent = true;
 
-                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
+                if (mHealthdConfig->batteryStatusPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -790,7 +790,7 @@
                         mHealthdConfig->batteryStatusPath = path;
                 }
 
-                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
+                if (mHealthdConfig->batteryHealthPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -798,7 +798,7 @@
                         mHealthdConfig->batteryHealthPath = path;
                 }
 
-                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
+                if (mHealthdConfig->batteryPresentPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -806,7 +806,7 @@
                         mHealthdConfig->batteryPresentPath = path;
                 }
 
-                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
+                if (mHealthdConfig->batteryCapacityPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -814,7 +814,7 @@
                         mHealthdConfig->batteryCapacityPath = path;
                 }
 
-                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
+                if (mHealthdConfig->batteryVoltagePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/voltage_now",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -823,7 +823,7 @@
                     }
                 }
 
-                if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
+                if (mHealthdConfig->batteryFullChargePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_full",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -831,7 +831,7 @@
                         mHealthdConfig->batteryFullChargePath = path;
                 }
 
-                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+                if (mHealthdConfig->batteryCurrentNowPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/current_now",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -839,7 +839,7 @@
                         mHealthdConfig->batteryCurrentNowPath = path;
                 }
 
-                if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+                if (mHealthdConfig->batteryCycleCountPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/cycle_count",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -847,27 +847,27 @@
                         mHealthdConfig->batteryCycleCountPath = path;
                 }
 
-                if (mHealthdConfig->batteryCapacityLevelPath.isEmpty()) {
+                if (mHealthdConfig->batteryCapacityLevelPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->batteryCapacityLevelPath = path;
                 }
 
-                if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) {
+                if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0)
                         mHealthdConfig->batteryChargeTimeToFullNowPath = path;
                 }
 
-                if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty()) {
+                if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0)
                         mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
                 }
 
-                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+                if (mHealthdConfig->batteryCurrentAvgPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/current_avg",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -875,7 +875,7 @@
                         mHealthdConfig->batteryCurrentAvgPath = path;
                 }
 
-                if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+                if (mHealthdConfig->batteryChargeCounterPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_counter",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -883,7 +883,7 @@
                         mHealthdConfig->batteryChargeCounterPath = path;
                 }
 
-                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
+                if (mHealthdConfig->batteryTemperaturePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -892,7 +892,7 @@
                     }
                 }
 
-                if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
+                if (mHealthdConfig->batteryTechnologyPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/technology",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -900,7 +900,7 @@
                         mHealthdConfig->batteryTechnologyPath = path;
                 }
 
-                if (mHealthdConfig->batteryStateOfHealthPath.isEmpty()) {
+                if (mHealthdConfig->batteryStateOfHealthPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/state_of_health", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) {
@@ -913,32 +913,32 @@
                     }
                 }
 
-                if (mHealthdConfig->batteryHealthStatusPath.isEmpty()) {
+                if (mHealthdConfig->batteryHealthStatusPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/health_status", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->batteryHealthStatusPath = path;
                 }
 
-                if (mHealthdConfig->batteryManufacturingDatePath.isEmpty()) {
+                if (mHealthdConfig->batteryManufacturingDatePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/manufacturing_date", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0)
                         mHealthdConfig->batteryManufacturingDatePath = path;
                 }
 
-                if (mHealthdConfig->batteryFirstUsageDatePath.isEmpty()) {
+                if (mHealthdConfig->batteryFirstUsageDatePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/first_usage_date", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->batteryFirstUsageDatePath = path;
                 }
 
-                if (mHealthdConfig->chargingStatePath.isEmpty()) {
+                if (mHealthdConfig->chargingStatePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charging_state", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->chargingStatePath = path;
                 }
 
-                if (mHealthdConfig->chargingPolicyPath.isEmpty()) {
+                if (mHealthdConfig->chargingPolicyPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charging_policy", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
@@ -968,43 +968,43 @@
         hc->periodic_chores_interval_fast = -1;
         hc->periodic_chores_interval_slow = -1;
     } else {
-        if (mHealthdConfig->batteryStatusPath.isEmpty())
+        if (mHealthdConfig->batteryStatusPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
-        if (mHealthdConfig->batteryHealthPath.isEmpty())
+        if (mHealthdConfig->batteryHealthPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
-        if (mHealthdConfig->batteryPresentPath.isEmpty())
+        if (mHealthdConfig->batteryPresentPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
-        if (mHealthdConfig->batteryCapacityPath.isEmpty())
+        if (mHealthdConfig->batteryCapacityPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
-        if (mHealthdConfig->batteryVoltagePath.isEmpty())
+        if (mHealthdConfig->batteryVoltagePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
-        if (mHealthdConfig->batteryTemperaturePath.isEmpty())
+        if (mHealthdConfig->batteryTemperaturePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
-        if (mHealthdConfig->batteryTechnologyPath.isEmpty())
+        if (mHealthdConfig->batteryTechnologyPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
-        if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
+        if (mHealthdConfig->batteryCurrentNowPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
-        if (mHealthdConfig->batteryFullChargePath.isEmpty())
+        if (mHealthdConfig->batteryFullChargePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
-        if (mHealthdConfig->batteryCycleCountPath.isEmpty())
+        if (mHealthdConfig->batteryCycleCountPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
-        if (mHealthdConfig->batteryCapacityLevelPath.isEmpty())
+        if (mHealthdConfig->batteryCapacityLevelPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
-        if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+        if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
-        if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+        if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
-        if (mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+        if (mHealthdConfig->batteryStateOfHealthPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryStateOfHealthPath not found\n");
-        if (mHealthdConfig->batteryHealthStatusPath.isEmpty())
+        if (mHealthdConfig->batteryHealthStatusPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryHealthStatusPath not found\n");
-        if (mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+        if (mHealthdConfig->batteryManufacturingDatePath.empty())
             KLOG_WARNING(LOG_TAG, "batteryManufacturingDatePath not found\n");
-        if (mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+        if (mHealthdConfig->batteryFirstUsageDatePath.empty())
             KLOG_WARNING(LOG_TAG, "batteryFirstUsageDatePath not found\n");
-        if (mHealthdConfig->chargingStatePath.isEmpty())
+        if (mHealthdConfig->chargingStatePath.empty())
             KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
-        if (mHealthdConfig->chargingPolicyPath.isEmpty())
+        if (mHealthdConfig->chargingPolicyPath.empty())
             KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
     }
 
diff --git a/healthd/BatteryMonitor_v1.cpp b/healthd/BatteryMonitor_v1.cpp
index b2d6518..686c338 100644
--- a/healthd/BatteryMonitor_v1.cpp
+++ b/healthd/BatteryMonitor_v1.cpp
@@ -301,7 +301,7 @@
 void BatteryMonitor::updateValues(void) {
     initHealthInfo(mHealthInfo.get());
 
-    if (!mHealthdConfig->batteryPresentPath.isEmpty())
+    if (!mHealthdConfig->batteryPresentPath.empty())
         mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
     else
         mHealthInfo->batteryPresent = mBatteryDevicePresent;
@@ -311,28 +311,28 @@
                                         : getIntField(mHealthdConfig->batteryCapacityPath);
     mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
+    if (!mHealthdConfig->batteryCurrentNowPath.empty())
         mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
 
-    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
+    if (!mHealthdConfig->batteryFullChargePath.empty())
         mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
 
-    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
+    if (!mHealthdConfig->batteryCycleCountPath.empty())
         mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
 
-    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
+    if (!mHealthdConfig->batteryChargeCounterPath.empty())
         mHealthInfo->batteryChargeCounterUah =
                 getIntField(mHealthdConfig->batteryChargeCounterPath);
 
-    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())
+    if (!mHealthdConfig->batteryCurrentAvgPath.empty())
         mHealthInfo->batteryCurrentAverageMicroamps =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
 
-    if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+    if (!mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
         mHealthInfo->batteryChargeTimeToFullNowSeconds =
                 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
 
-    if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+    if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
         mHealthInfo->batteryFullChargeDesignCapacityUah =
                 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
 
@@ -420,17 +420,17 @@
                  props.batteryStatus);
 
         len = strlen(dmesgline);
-        if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
+        if (!healthd_config.batteryCurrentNowPath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
                             props.batteryCurrentMicroamps);
         }
 
-        if (!healthd_config.batteryFullChargePath.isEmpty()) {
+        if (!healthd_config.batteryFullChargePath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
                             props.batteryFullChargeUah);
         }
 
-        if (!healthd_config.batteryCycleCountPath.isEmpty()) {
+        if (!healthd_config.batteryCycleCountPath.empty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
                             props.batteryCycleCount);
         }
@@ -464,7 +464,7 @@
 
 int BatteryMonitor::getChargeStatus() {
     BatteryStatus result = BatteryStatus::UNKNOWN;
-    if (!mHealthdConfig->batteryStatusPath.isEmpty()) {
+    if (!mHealthdConfig->batteryStatusPath.empty()) {
         std::string buf;
         if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
             result = getBatteryStatus(buf.c_str());
@@ -480,7 +480,7 @@
 
     switch(id) {
     case BATTERY_PROP_CHARGE_COUNTER:
-        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+        if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryChargeCounterPath);
             ret = OK;
@@ -490,7 +490,7 @@
         break;
 
     case BATTERY_PROP_CURRENT_NOW:
-        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentNowPath);
             ret = OK;
@@ -500,7 +500,7 @@
         break;
 
     case BATTERY_PROP_CURRENT_AVG:
-        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
             ret = OK;
@@ -510,7 +510,7 @@
         break;
 
     case BATTERY_PROP_CAPACITY:
-        if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
+        if (!mHealthdConfig->batteryCapacityPath.empty()) {
             val->valueInt64 =
                 getIntField(mHealthdConfig->batteryCapacityPath);
             ret = OK;
@@ -557,35 +557,35 @@
              props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
     write(fd, vs, strlen(vs));
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
         v = getIntField(mHealthdConfig->batteryCurrentNowPath);
         snprintf(vs, sizeof(vs), "current now: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
         v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
         snprintf(vs, sizeof(vs), "current avg: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+    if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
         v = getIntField(mHealthdConfig->batteryChargeCounterPath);
         snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
         snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+    if (!mHealthdConfig->batteryCycleCountPath.empty()) {
         snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
         write(fd, vs, strlen(vs));
     }
 
-    if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
+    if (!mHealthdConfig->batteryFullChargePath.empty()) {
         snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
         write(fd, vs, strlen(vs));
     }
@@ -635,7 +635,7 @@
                 if (isScopedPowerSupply(name)) continue;
                 mBatteryDevicePresent = true;
 
-                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
+                if (mHealthdConfig->batteryStatusPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -643,7 +643,7 @@
                         mHealthdConfig->batteryStatusPath = path;
                 }
 
-                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
+                if (mHealthdConfig->batteryHealthPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -651,7 +651,7 @@
                         mHealthdConfig->batteryHealthPath = path;
                 }
 
-                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
+                if (mHealthdConfig->batteryPresentPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -659,7 +659,7 @@
                         mHealthdConfig->batteryPresentPath = path;
                 }
 
-                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
+                if (mHealthdConfig->batteryCapacityPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -667,7 +667,7 @@
                         mHealthdConfig->batteryCapacityPath = path;
                 }
 
-                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
+                if (mHealthdConfig->batteryVoltagePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/voltage_now",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -676,7 +676,7 @@
                     }
                 }
 
-                if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
+                if (mHealthdConfig->batteryFullChargePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_full",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -684,7 +684,7 @@
                         mHealthdConfig->batteryFullChargePath = path;
                 }
 
-                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+                if (mHealthdConfig->batteryCurrentNowPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/current_now",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -692,7 +692,7 @@
                         mHealthdConfig->batteryCurrentNowPath = path;
                 }
 
-                if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+                if (mHealthdConfig->batteryCycleCountPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/cycle_count",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -700,27 +700,27 @@
                         mHealthdConfig->batteryCycleCountPath = path;
                 }
 
-                if (mHealthdConfig->batteryCapacityLevelPath.isEmpty()) {
+                if (mHealthdConfig->batteryCapacityLevelPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0) mHealthdConfig->batteryCapacityLevelPath = path;
                 }
 
-                if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) {
+                if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0)
                         mHealthdConfig->batteryChargeTimeToFullNowPath = path;
                 }
 
-                if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty()) {
+                if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
                     if (access(path, R_OK) == 0)
                         mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
                 }
 
-                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+                if (mHealthdConfig->batteryCurrentAvgPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/current_avg",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -728,7 +728,7 @@
                         mHealthdConfig->batteryCurrentAvgPath = path;
                 }
 
-                if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+                if (mHealthdConfig->batteryChargeCounterPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/charge_counter",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -736,7 +736,7 @@
                         mHealthdConfig->batteryChargeCounterPath = path;
                 }
 
-                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
+                if (mHealthdConfig->batteryTemperaturePath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
                                       name);
@@ -745,7 +745,7 @@
                     }
                 }
 
-                if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
+                if (mHealthdConfig->batteryTechnologyPath.empty()) {
                     path.clear();
                     path.appendFormat("%s/%s/technology",
                                       POWER_SUPPLY_SYSFS_PATH, name);
@@ -777,31 +777,31 @@
         hc->periodic_chores_interval_fast = -1;
         hc->periodic_chores_interval_slow = -1;
     } else {
-        if (mHealthdConfig->batteryStatusPath.isEmpty())
+        if (mHealthdConfig->batteryStatusPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
-        if (mHealthdConfig->batteryHealthPath.isEmpty())
+        if (mHealthdConfig->batteryHealthPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
-        if (mHealthdConfig->batteryPresentPath.isEmpty())
+        if (mHealthdConfig->batteryPresentPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
-        if (mHealthdConfig->batteryCapacityPath.isEmpty())
+        if (mHealthdConfig->batteryCapacityPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
-        if (mHealthdConfig->batteryVoltagePath.isEmpty())
+        if (mHealthdConfig->batteryVoltagePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
-        if (mHealthdConfig->batteryTemperaturePath.isEmpty())
+        if (mHealthdConfig->batteryTemperaturePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
-        if (mHealthdConfig->batteryTechnologyPath.isEmpty())
+        if (mHealthdConfig->batteryTechnologyPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
-        if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
+        if (mHealthdConfig->batteryCurrentNowPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
-        if (mHealthdConfig->batteryFullChargePath.isEmpty())
+        if (mHealthdConfig->batteryFullChargePath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
-        if (mHealthdConfig->batteryCycleCountPath.isEmpty())
+        if (mHealthdConfig->batteryCycleCountPath.empty())
             KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
-        if (mHealthdConfig->batteryCapacityLevelPath.isEmpty())
+        if (mHealthdConfig->batteryCapacityLevelPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
-        if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+        if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
-        if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+        if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
             KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
     }
 
diff --git a/init/TEST_MAPPING b/init/TEST_MAPPING
index 402b501..36ca379 100644
--- a/init/TEST_MAPPING
+++ b/init/TEST_MAPPING
@@ -8,14 +8,6 @@
     },
     {
       "name": "MicrodroidHostTestCases"
-    },
-    {
-      "name": "CtsSecurityHostTestCases",
-      "options": [
-        {
-          "include-filter": "android.security.cts.SeamendcHostTest"
-        }
-      ]
     }
   ],
   "hwasan-presubmit": [
@@ -27,14 +19,6 @@
     },
     {
       "name": "MicrodroidHostTestCases"
-    },
-    {
-      "name": "CtsSecurityHostTestCases",
-      "options": [
-        {
-          "include-filter": "android.security.cts.SeamendcHostTest"
-        }
-      ]
     }
   ]
 }
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 3239eb7..c6a287a 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -163,6 +163,21 @@
     return android::base::StringPrintf("_%zuk", page_size / 1024);
 }
 
+constexpr bool EndsWith(const std::string_view str, const std::string_view suffix) {
+    return str.size() >= suffix.size() &&
+           0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
+}
+
+constexpr std::string_view GetPageSizeSuffix(std::string_view dirname) {
+    if (EndsWith(dirname, "_16k")) {
+        return "_16k";
+    }
+    if (EndsWith(dirname, "_64k")) {
+        return "_64k";
+    }
+    return "";
+}
+
 }  // namespace
 
 std::string GetModuleLoadList(BootMode boot_mode, const std::string& dir_path) {
@@ -211,7 +226,8 @@
     }
     dirent* entry = nullptr;
     std::vector<std::string> module_dirs;
-    const std::string release_specific_module_dir = uts.release + GetPageSizeSuffix();
+    const auto page_size_suffix = GetPageSizeSuffix();
+    const std::string release_specific_module_dir = uts.release + page_size_suffix;
     while ((entry = readdir(base_dir.get()))) {
         if (entry->d_type != DT_DIR) {
             continue;
@@ -223,6 +239,10 @@
             module_dirs.emplace_back(entry->d_name);
             break;
         }
+        // Ignore _16k/_64k module dirs on 4K kernels
+        if (GetPageSizeSuffix(entry->d_name) != page_size_suffix) {
+            continue;
+        }
         int dir_major = 0, dir_minor = 0;
         if (sscanf(entry->d_name, "%d.%d", &dir_major, &dir_minor) != 2 || dir_major != major ||
             dir_minor != minor) {
diff --git a/init/service.h b/init/service.h
index b858eef..9f09cef 100644
--- a/init/service.h
+++ b/init/service.h
@@ -60,7 +60,7 @@
 #define SVC_GENTLE_KILL 0x2000  // This service should be stopped with SIGTERM instead of SIGKILL
                                 // Will still be SIGKILLed after timeout period of 200 ms
 
-#define NR_SVC_SUPP_GIDS 12    // twelve supplementary groups
+#define NR_SVC_SUPP_GIDS 32    // thirty two supplementary groups
 
 namespace android {
 namespace init {
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index 5a7d0fc..44907a1 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -41,9 +41,8 @@
     ],
 }
 
-cc_binary {
+cc_binary_host {
     name: "simg2img",
-    host_supported: true,
     srcs: [
         "simg2img.cpp",
         "sparse_crc32.cpp",
@@ -62,9 +61,8 @@
     },
 }
 
-cc_binary {
+cc_binary_host {
     name: "img2simg",
-    host_supported: true,
     srcs: ["img2simg.cpp"],
     static_libs: [
         "libsparse",
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 79b7edf..2b72847 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -39,10 +39,6 @@
 
 namespace android {
 
-// Separator used by resource paths. This is not platform dependent contrary
-// to OS_PATH_SEPARATOR.
-#define RES_PATH_SEPARATOR '/'
-
 static inline char* getEmptyString() {
     static SharedBuffer* gEmptyStringBuf = [] {
         SharedBuffer* buf = SharedBuffer::alloc(1);
@@ -582,20 +578,4 @@
     }
 }
 
-String8& String8::convertToResPath()
-{
-#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
-    size_t len = length();
-    if (len > 0) {
-        char * buf = lockBuffer(len);
-        for (char * end = buf + len; buf < end; ++buf) {
-            if (*buf == OS_PATH_SEPARATOR)
-                *buf = RES_PATH_SEPARATOR;
-        }
-        unlockBuffer(len);
-    }
-#endif
-    return *this;
-}
-
 }; // namespace android
diff --git a/libutils/String8_fuzz.cpp b/libutils/String8_fuzz.cpp
index e5dcd31..6f7a54f 100644
--- a/libutils/String8_fuzz.cpp
+++ b/libutils/String8_fuzz.cpp
@@ -34,7 +34,7 @@
                     str1->bytes();
                 },
                 [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->isEmpty();
+                    str1->empty();
                 },
                 [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
                     str1->length();
@@ -83,9 +83,6 @@
                     str1->getPathDir();
                 },
                 [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->convertToResPath();
-                },
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
                     std::shared_ptr<android::String8> path_out_str =
                             std::make_shared<android::String8>();
                     str1->walkPath(path_out_str.get());
diff --git a/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump b/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
index c89af9e..46badde 100644
--- a/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
+++ b/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
@@ -725,9 +725,6 @@
    "name" : "_ZN7android7String813appendFormatVEPKcSt9__va_list"
   },
   {
-   "name" : "_ZN7android7String816convertToResPathEv"
-  },
-  {
    "name" : "_ZN7android7String85clearEv"
   },
   {
@@ -6928,19 +6925,6 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::convertToResPath",
-   "linker_set_key" : "_ZN7android7String816convertToResPathEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIRN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::clear",
    "linker_set_key" : "_ZN7android7String85clearEv",
    "parameters" :
diff --git a/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump b/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
index f88da15..219c766 100644
--- a/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
+++ b/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
@@ -725,9 +725,6 @@
    "name" : "_ZN7android7String813appendFormatVEPKcSt9__va_list"
   },
   {
-   "name" : "_ZN7android7String816convertToResPathEv"
-  },
-  {
    "name" : "_ZN7android7String85clearEv"
   },
   {
@@ -6924,19 +6921,6 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::convertToResPath",
-   "linker_set_key" : "_ZN7android7String816convertToResPathEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIRN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::clear",
    "linker_set_key" : "_ZN7android7String85clearEv",
    "parameters" :
diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h
index d719aea..b48b907 100644
--- a/libutils/include/utils/String16.h
+++ b/libutils/include/utils/String16.h
@@ -60,6 +60,10 @@
     static inline std::string   std_string(const String16& str);
 public:
             size_t              size() const;
+    inline  bool                empty() const;
+
+    inline  size_t              length() const;
+
             void                setTo(const String16& other);
             status_t            setTo(const char16_t* other);
             status_t            setTo(const char16_t* other, size_t len);
@@ -250,6 +254,16 @@
     return std::string(String8(str).c_str());
 }
 
+inline bool String16::empty() const
+{
+    return length() == 0;
+}
+
+inline size_t String16::length() const
+{
+    return size();
+}
+
 inline String16& String16::operator=(const String16& other)
 {
     setTo(other);
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index ace0243..ea25c6a 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -64,6 +64,7 @@
 
     inline  size_t              size() const;
     inline  size_t              bytes() const;
+    inline  bool                empty() const;
     inline  bool                isEmpty() const;
 
             size_t              length() const;
@@ -200,15 +201,6 @@
                                              { String8 p(*this); p.appendPath(leaf); return p; }
     String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.c_str()); }
 
-    /*
-     * Converts all separators in this string to /, the default path separator.
-     *
-     * If the default OS separator is backslash, this converts all
-     * backslashes to slashes, in-place. Otherwise it does nothing.
-     * Returns self.
-     */
-    String8& convertToResPath();
-
 private:
             status_t            real_append(const char* other, size_t numChars);
             char*               find_extension(void) const;
@@ -257,6 +249,11 @@
     return length();
 }
 
+inline bool String8::empty() const
+{
+    return length() == 0;
+}
+
 inline bool String8::isEmpty() const
 {
     return length() == 0;
diff --git a/trusty/utils/coverage-controller/controller.cpp b/trusty/utils/coverage-controller/controller.cpp
index 730c010..0047046 100644
--- a/trusty/utils/coverage-controller/controller.cpp
+++ b/trusty/utils/coverage-controller/controller.cpp
@@ -14,11 +14,16 @@
  * limitations under the License.
  */
 
+#include <android-base/stringprintf.h>
+#include <array>
 #include <getopt.h>
+#include <inttypes.h>
+#include <memory>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
 #include <trusty/line-coverage/coverage.h>
 #include <trusty/tipc.h>
-#include <array>
-#include <memory>
 #include <vector>
 
 #include "controller.h"
@@ -48,10 +53,10 @@
 
             if (complete_cnt != counters[index] && start_cnt == complete_cnt) {
                 WRITE_ONCE(control->cntrl_flags, FLAG_NONE);
-                std::string fmt = "/%d.%lu.profraw";
-                int sz = std::snprintf(nullptr, 0, fmt.c_str(), index, counters[index]);
-                std::string filename(sz+1, '.');
-                std::sprintf(filename.data(), fmt.c_str(), index, counters[index]);
+                std::string filename;
+                filename = android::base::StringPrintf("/%s.%lu.profraw",
+                                                    uuid_list_[index].c_str(),
+                                                    counters[index]);
                 filename.insert(0, output_dir);
                 android::base::Result<void> res = record_list_[index]->SaveFile(filename);
                 counters[index]++;
@@ -79,6 +84,7 @@
     struct line_coverage_client_resp resp;
     uint32_t cur_index = record_list_.size();
     struct uuid zero_uuid = {0, 0, 0, { 0 }};
+    char uuid_str[UUID_STR_SIZE];
     req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_SEND_LIST;
     int rc = write(coverage_srv_fd, &req, sizeof(req));
         if (rc != (int)sizeof(req)) {
@@ -98,6 +104,21 @@
             }
             if(uuid_set_.find(resp.send_list_args.uuid) == uuid_set_.end()) {
                 uuid_set_.insert(resp.send_list_args.uuid);
+                sprintf(uuid_str,
+                    "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-%02" PRIx8 "%02" PRIx8
+                    "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
+                    resp.send_list_args.uuid.time_low,
+                    resp.send_list_args.uuid.time_mid,
+                    resp.send_list_args.uuid.time_hi_and_version,
+                    resp.send_list_args.uuid.clock_seq_and_node[0],
+                    resp.send_list_args.uuid.clock_seq_and_node[1],
+                    resp.send_list_args.uuid.clock_seq_and_node[2],
+                    resp.send_list_args.uuid.clock_seq_and_node[3],
+                    resp.send_list_args.uuid.clock_seq_and_node[4],
+                    resp.send_list_args.uuid.clock_seq_and_node[5],
+                    resp.send_list_args.uuid.clock_seq_and_node[6],
+                    resp.send_list_args.uuid.clock_seq_and_node[7]);
+                uuid_list_.push_back(uuid_str);
                 record_list_.push_back(std::make_unique<CoverageRecord>(TIPC_DEV,
                                                                     &resp.send_list_args.uuid));
                 counters.push_back(0);
diff --git a/trusty/utils/coverage-controller/controller.h b/trusty/utils/coverage-controller/controller.h
index b771c16..f7789bf 100644
--- a/trusty/utils/coverage-controller/controller.h
+++ b/trusty/utils/coverage-controller/controller.h
@@ -26,6 +26,8 @@
 #define TEST_SRV_PORT "com.android.trusty.sancov.test.srv"
 #define TEST_SRV_MODULE "srv.syms.elf"
 
+#define UUID_STR_SIZE (37)
+
 #define FLAG_NONE               0x0
 #define FLAG_RUN                0x1
 #define FLAG_TOGGLE_CLEAR       0x2
@@ -52,6 +54,7 @@
     private:
         std::vector<std::unique_ptr<line_coverage::CoverageRecord>>record_list_;
         std::set<struct uuid>uuid_set_;
+        std::vector<std::string>uuid_list_;
         std::vector<uint64_t> counters;
         int coverage_srv_fd;