Merge "snapuserd: Restrict where reads/writes to dm_user_header happen." into main
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 30eb7b5..2941216 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -76,6 +76,7 @@
 #include "constants.h"
 #include "diagnose_usb.h"
 #include "fastboot_driver.h"
+#include "fastboot_driver_interface.h"
 #include "fs.h"
 #include "storage.h"
 #include "super_flash_helper.h"
@@ -173,7 +174,7 @@
         // clang-format on
 };
 
-static char* get_android_product_out() {
+char* get_android_product_out() {
     char* dir = getenv("ANDROID_PRODUCT_OUT");
     if (dir == nullptr || dir[0] == '\0') {
         return nullptr;
@@ -996,7 +997,7 @@
     return resparse_file(s.get(), max_size);
 }
 
-static uint64_t get_uint_var(const char* var_name) {
+static uint64_t get_uint_var(const char* var_name, fastboot::IFastBootDriver* fb) {
     std::string value_str;
     if (fb->GetVar(var_name, &value_str) != fastboot::SUCCESS || value_str.empty()) {
         verbose("target didn't report %s", var_name);
@@ -1021,7 +1022,7 @@
         // Unlimited, so see what the target device's limit is.
         // TODO: shouldn't we apply this limit even if you've used -S?
         if (target_sparse_limit == -1) {
-            target_sparse_limit = static_cast<int64_t>(get_uint_var("max-download-size"));
+            target_sparse_limit = static_cast<int64_t>(get_uint_var("max-download-size", fp->fb));
         }
         if (target_sparse_limit > 0) {
             limit = target_sparse_limit;
@@ -1410,7 +1411,7 @@
     }
 }
 
-bool is_retrofit_device() {
+bool is_retrofit_device(fastboot::IFastBootDriver* fb) {
     std::string value;
     if (fb->GetVar("super-partition-name", &value) != fastboot::SUCCESS) {
         return false;
@@ -1420,8 +1421,9 @@
 
 // Fetch a partition from the device to a given fd. This is a wrapper over FetchToFd to fetch
 // the full image.
-static uint64_t fetch_partition(const std::string& partition, borrowed_fd fd) {
-    uint64_t fetch_size = get_uint_var(FB_VAR_MAX_FETCH_SIZE);
+static uint64_t fetch_partition(const std::string& partition, borrowed_fd fd,
+                                fastboot::IFastBootDriver* fb) {
+    uint64_t fetch_size = get_uint_var(FB_VAR_MAX_FETCH_SIZE, fb);
     if (fetch_size == 0) {
         die("Unable to get %s. Device does not support fetch command.", FB_VAR_MAX_FETCH_SIZE);
     }
@@ -1443,17 +1445,18 @@
 }
 
 static void do_fetch(const std::string& partition, const std::string& slot_override,
-                     const std::string& outfile) {
+                     const std::string& outfile, fastboot::IFastBootDriver* fb) {
     unique_fd fd(TEMP_FAILURE_RETRY(
             open(outfile.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, 0644)));
-    auto fetch = std::bind(fetch_partition, _1, borrowed_fd(fd));
+    auto fetch = std::bind(fetch_partition, _1, borrowed_fd(fd), fb);
     do_for_partitions(partition, slot_override, fetch, false /* force slot */);
 }
 
 // Return immediately if not flashing a vendor boot image. If flashing a vendor boot image,
 // repack vendor_boot image with an updated ramdisk. After execution, buf is set
 // to the new image to flash, and return value is the real partition name to flash.
-static std::string repack_ramdisk(const char* pname, struct fastboot_buffer* buf) {
+static std::string repack_ramdisk(const char* pname, struct fastboot_buffer* buf,
+                                  fastboot::IFastBootDriver* fb) {
     std::string_view pname_sv{pname};
 
     if (!android::base::StartsWith(pname_sv, "vendor_boot:") &&
@@ -1471,7 +1474,7 @@
     std::string ramdisk(pname_sv.substr(pname_sv.find(':') + 1));
 
     unique_fd vendor_boot(make_temporary_fd("vendor boot repack"));
-    uint64_t vendor_boot_size = fetch_partition(partition, vendor_boot);
+    uint64_t vendor_boot_size = fetch_partition(partition, vendor_boot, fb);
     auto repack_res = replace_vendor_ramdisk(vendor_boot, vendor_boot_size, ramdisk, buf->fd,
                                              static_cast<uint64_t>(buf->sz));
     if (!repack_res.ok()) {
@@ -1486,10 +1489,13 @@
 
 void do_flash(const char* pname, const char* fname, const bool apply_vbmeta,
               const FlashingPlan* fp) {
+    if (!fp) {
+        die("do flash was called without a valid flashing plan");
+    }
     verbose("Do flash %s %s", pname, fname);
     struct fastboot_buffer buf;
 
-    if (fp && fp->source) {
+    if (fp->source) {
         unique_fd fd = fp->source->OpenFile(fname);
         if (fd < 0 || !load_buf_fd(std::move(fd), &buf, fp)) {
             die("could not load '%s': %s", fname, strerror(errno));
@@ -1508,7 +1514,7 @@
     if (is_logical(pname)) {
         fb->ResizePartition(pname, std::to_string(buf.image_size));
     }
-    std::string flash_pname = repack_ramdisk(pname, &buf);
+    std::string flash_pname = repack_ramdisk(pname, &buf, fp->fb);
     flash_buf(flash_pname, &buf, apply_vbmeta);
 }
 
@@ -1747,7 +1753,7 @@
         }
         tasks.emplace_back(std::move(task));
     }
-    if (auto flash_super_task = FlashSuperLayoutTask::InitializeFromTasks(fp, tasks)) {
+    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()) {
@@ -1787,13 +1793,25 @@
 
     CancelSnapshotIfNeeded();
 
-    tasks_ = CollectTasksFromImageList();
+    tasks_ = CollectTasks();
     for (auto& task : tasks_) {
         task->Run();
     }
     return;
 }
 
+std::vector<std::unique_ptr<Task>> FlashAllTool::CollectTasks() {
+    std::vector<std::unique_ptr<Task>> tasks;
+    if (fp_->should_use_fastboot_info) {
+        tasks = CollectTasksFromFastbootInfo();
+
+    } else {
+        tasks = CollectTasksFromImageList();
+    }
+
+    return tasks;
+}
+
 void FlashAllTool::CheckRequirements() {
     std::vector<char> contents;
     if (!fp_->source->ReadFile("android-info.txt", &contents)) {
@@ -1848,8 +1866,7 @@
     // or in bootloader fastboot.
     std::vector<std::unique_ptr<Task>> tasks;
     AddFlashTasks(boot_images_, tasks);
-
-    if (auto flash_super_task = FlashSuperLayoutTask::Initialize(fp_, os_images_)) {
+    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.
@@ -1861,7 +1878,7 @@
             // 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()) {
+            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);
@@ -1871,10 +1888,23 @@
             tasks.emplace_back(std::make_unique<ResizeTask>(fp_, image->part_name, "0", slot));
         }
     }
+
     AddFlashTasks(os_images_, tasks);
     return tasks;
 }
 
+std::vector<std::unique_ptr<Task>> FlashAllTool::CollectTasksFromFastbootInfo() {
+    std::vector<std::unique_ptr<Task>> tasks;
+    std::vector<char> contents;
+    if (!fp_->source->ReadFile("fastboot-info.txt", &contents)) {
+        LOG(VERBOSE) << "Flashing from hardcoded images. fastboot-info.txt is empty or does not "
+                        "exist";
+        return CollectTasksFromImageList();
+    }
+    tasks = ParseFastbootInfo(fp_, Split({contents.data(), contents.size()}, "\n"));
+    return tasks;
+}
+
 void FlashAllTool::AddFlashTasks(const std::vector<std::pair<const Image*, std::string>>& images,
                                  std::vector<std::unique_ptr<Task>>& tasks) {
     for (const auto& [image, slot] : images) {
@@ -2205,8 +2235,9 @@
                                       {0, 0, 0, 0}};
 
     serial = getenv("FASTBOOT_DEVICE");
-    if (!serial)
+    if (!serial) {
         serial = getenv("ANDROID_SERIAL");
+    }
 
     int c;
     while ((c = getopt_long(argc, argv, "a::hls:S:vw", longopts, &longindex)) != -1) {
@@ -2551,7 +2582,7 @@
         } else if (command == FB_CMD_FETCH) {
             std::string partition = next_arg(&args);
             std::string outfile = next_arg(&args);
-            do_fetch(partition, fp->slot_override, outfile);
+            do_fetch(partition, fp->slot_override, outfile, fp->fb);
         } else {
             syntax_error("unknown command %s", command.c_str());
         }
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 196bd67..50db25d 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -97,6 +97,7 @@
     bool skip_secondary = false;
     bool force_flash = false;
     bool should_optimize_flash_super = true;
+    bool should_use_fastboot_info = false;
     uint64_t sparse_limit = 0;
 
     std::string slot_override;
@@ -111,6 +112,7 @@
     FlashAllTool(FlashingPlan* fp);
 
     void Flash();
+    std::vector<std::unique_ptr<Task>> CollectTasks();
 
   private:
     void CheckRequirements();
@@ -118,6 +120,8 @@
     void CollectImages();
     void AddFlashTasks(const std::vector<std::pair<const Image*, std::string>>& images,
                        std::vector<std::unique_ptr<Task>>& tasks);
+
+    std::vector<std::unique_ptr<Task>> CollectTasksFromFastbootInfo();
     std::vector<std::unique_ptr<Task>> CollectTasksFromImageList();
 
     std::vector<ImageEntry> boot_images_;
@@ -143,6 +147,7 @@
     unique_fd OpenFile(const std::string& name) const override;
 };
 
+char* get_android_product_out();
 bool should_flash_in_userspace(const std::string& partition_name);
 bool is_userspace_fastboot();
 void do_flash(const char* pname, const char* fname, const bool apply_vbmeta,
@@ -182,7 +187,7 @@
 int64_t get_sparse_limit(int64_t size, const FlashingPlan* fp);
 std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);
 
-bool is_retrofit_device();
+bool is_retrofit_device(fastboot::IFastBootDriver* fb);
 bool is_logical(const std::string& partition);
 void fb_perform_format(const std::string& partition, int skip_if_not_supported,
                        const std::string& type_override, const std::string& size_override,
diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h
index 6ac26ce..8774ead 100644
--- a/fastboot/fastboot_driver.h
+++ b/fastboot/fastboot_driver.h
@@ -105,7 +105,7 @@
                                   std::vector<std::string>* info = nullptr);
     RetCode FetchToFd(const std::string& partition, android::base::borrowed_fd fd,
                       int64_t offset = -1, int64_t size = -1, std::string* response = nullptr,
-                      std::vector<std::string>* info = nullptr);
+                      std::vector<std::string>* info = nullptr) override;
 
     /* HIGHER LEVEL COMMANDS -- Composed of the commands above */
     RetCode FlashPartition(const std::string& partition, const std::vector<char>& data);
diff --git a/fastboot/fastboot_driver_interface.h b/fastboot/fastboot_driver_interface.h
index 795938f..7cb8a6b 100644
--- a/fastboot/fastboot_driver_interface.h
+++ b/fastboot/fastboot_driver_interface.h
@@ -45,6 +45,10 @@
                              std::vector<std::string>* info = nullptr) = 0;
     RetCode virtual GetVar(const std::string& key, std::string* val,
                            std::vector<std::string>* info = nullptr) = 0;
+    RetCode virtual FetchToFd(const std::string& partition, android::base::borrowed_fd fd,
+                              int64_t offset = -1, int64_t size = -1,
+                              std::string* response = nullptr,
+                              std::vector<std::string>* info = nullptr) = 0;
     RetCode virtual Download(const std::string& name, android::base::borrowed_fd fd, size_t size,
                              std::string* response = nullptr,
                              std::vector<std::string>* info = nullptr) = 0;
diff --git a/fastboot/fastboot_driver_mock.h b/fastboot/fastboot_driver_mock.h
index d2a123b..7c41d78 100644
--- a/fastboot/fastboot_driver_mock.h
+++ b/fastboot/fastboot_driver_mock.h
@@ -28,15 +28,16 @@
     MOCK_METHOD(RetCode, Reboot, (std::string*, std::vector<std::string>*), (override));
     MOCK_METHOD(RetCode, RebootTo, (std::string, std::string*, std::vector<std::string>*),
                 (override));
-
     MOCK_METHOD(RetCode, GetVar, (const std::string&, std::string*, std::vector<std::string>*),
                 (override));
-
+    MOCK_METHOD(RetCode, FetchToFd,
+                (const std::string&, android::base::borrowed_fd, int64_t offset, int64_t size,
+                 std::string*, std::vector<std::string>*),
+                (override));
     MOCK_METHOD(RetCode, Download,
                 (const std::string&, android::base::borrowed_fd, size_t, std::string*,
                  std::vector<std::string>*),
                 (override));
-
     MOCK_METHOD(RetCode, RawCommand,
                 (const std::string&, const std::string&, std::string*, std::vector<std::string>*,
                  int*),
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index c1b9a31..bf64f0e 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -96,17 +96,17 @@
     return "reboot " + reboot_target_;
 }
 
-FlashSuperLayoutTask::FlashSuperLayoutTask(const std::string& super_name,
-                                           std::unique_ptr<SuperFlashHelper> helper,
-                                           SparsePtr sparse_layout, uint64_t super_size,
-                                           const FlashingPlan* fp)
+OptimizedFlashSuperTask::OptimizedFlashSuperTask(const std::string& super_name,
+                                                 std::unique_ptr<SuperFlashHelper> helper,
+                                                 SparsePtr sparse_layout, uint64_t super_size,
+                                                 const FlashingPlan* fp)
     : super_name_(super_name),
       helper_(std::move(helper)),
       sparse_layout_(std::move(sparse_layout)),
       super_size_(super_size),
       fp_(fp) {}
 
-void FlashSuperLayoutTask::Run() {
+void OptimizedFlashSuperTask::Run() {
     // Use the reported super partition size as the upper limit, rather than
     // sparse_file_len, which (1) can fail and (2) is kind of expensive, since
     // it will map in all of the embedded fds.
@@ -120,11 +120,11 @@
     // Send the data to the device.
     flash_partition_files(super_name_, files);
 }
-std::string FlashSuperLayoutTask::ToString() {
+std::string OptimizedFlashSuperTask::ToString() {
     return "optimized-flash-super";
 }
 
-std::unique_ptr<FlashSuperLayoutTask> FlashSuperLayoutTask::Initialize(
+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";
@@ -188,11 +188,11 @@
     };
     os_images.erase(std::remove_if(os_images.begin(), os_images.end(), remove_if_callback),
                     os_images.end());
-    return std::make_unique<FlashSuperLayoutTask>(super_name, std::move(helper), std::move(s),
-                                                  partition_size, fp);
+    return std::make_unique<OptimizedFlashSuperTask>(super_name, std::move(helper), std::move(s),
+                                                     partition_size, fp);
 }
 
-std::unique_ptr<FlashSuperLayoutTask> FlashSuperLayoutTask::InitializeFromTasks(
+std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::InitializeFromTasks(
         const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks) {
     if (!fp->should_optimize_flash_super) {
         LOG(INFO) << "super optimization is disabled";
@@ -261,8 +261,8 @@
     };
     tasks.erase(std::remove_if(tasks.begin(), tasks.end(), remove_if_callback), tasks.end());
 
-    return std::make_unique<FlashSuperLayoutTask>(super_name, std::move(helper), std::move(s),
-                                                  partition_size, fp);
+    return std::make_unique<OptimizedFlashSuperTask>(super_name, std::move(helper), std::move(s),
+                                                     partition_size, fp);
 }
 
 UpdateSuperTask::UpdateSuperTask(const FlashingPlan* fp) : fp_(fp) {}
diff --git a/fastboot/task.h b/fastboot/task.h
index 858f43a..f7c8801 100644
--- a/fastboot/task.h
+++ b/fastboot/task.h
@@ -79,13 +79,13 @@
     const FlashingPlan* fp_;
 };
 
-class FlashSuperLayoutTask : public Task {
+class OptimizedFlashSuperTask : public Task {
   public:
-    FlashSuperLayoutTask(const std::string& super_name, std::unique_ptr<SuperFlashHelper> helper,
-                         SparsePtr sparse_layout, uint64_t super_size, const FlashingPlan* fp);
-    static std::unique_ptr<FlashSuperLayoutTask> Initialize(const FlashingPlan* fp,
-                                                            std::vector<ImageEntry>& os_images);
-    static std::unique_ptr<FlashSuperLayoutTask> InitializeFromTasks(
+    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(
             const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks);
     using ImageEntry = std::pair<const Image*, std::string>;
     void Run() override;
diff --git a/fastboot/task_test.cpp b/fastboot/task_test.cpp
index b4e139b..1ba3f4a 100644
--- a/fastboot/task_test.cpp
+++ b/fastboot/task_test.cpp
@@ -24,6 +24,7 @@
 #include <memory>
 #include <unordered_map>
 #include "android-base/strings.h"
+
 using android::base::Split;
 using testing::_;
 
@@ -60,6 +61,33 @@
     return ParseFastbootInfoLine(fp, vec_command);
 }
 
+// tests if tasks_a is a superset of tasks_b. Used for checking to ensure all partitions flashed
+// from hardcoded image list is also flashed in new fastboot-info.txt
+static bool compareTaskList(std::vector<std::unique_ptr<Task>>& tasks_a,
+                            std::vector<std::unique_ptr<Task>>& tasks_b) {
+    std::set<std::string> list;
+    for (auto& task : tasks_a) {
+        list.insert(task->ToString());
+    }
+    for (auto& task : tasks_b) {
+        if (list.find(task->ToString()) == list.end()) {
+            std::cout << "ERROR: " << task->ToString()
+                      << " not found in task list created by fastboot-info.txt";
+            return false;
+        }
+    }
+    return true;
+}
+
+static std::string tasksToString(std::vector<std::unique_ptr<Task>>& tasks) {
+    std::string output;
+    for (auto& task : tasks) {
+        output.append(task->ToString());
+        output.append("\n");
+    }
+    return output;
+}
+
 TEST_F(ParseTest, CorrectFlashTaskFormed) {
     std::vector<std::string> commands = {"flash dtbo", "flash --slot-other system system_other.img",
                                          "flash system", "flash --apply-vbmeta vbmeta"};
@@ -159,3 +187,51 @@
         task->Run();
     }
 }
+
+TEST_F(ParseTest, CorrectTaskLists) {
+    if (!get_android_product_out()) {
+        GTEST_SKIP();
+    }
+
+    LocalImageSource s;
+    fp->source = &s;
+    fp->sparse_limit = std::numeric_limits<int64_t>::max();
+
+    fastboot::MockFastbootDriver fb;
+    fp->fb = &fb;
+    fp->should_optimize_flash_super = false;
+
+    ON_CALL(fb, GetVar("super-partition-name", _, _))
+            .WillByDefault(testing::Return(fastboot::BAD_ARG));
+
+    FlashAllTool tool(fp.get());
+
+    fp->should_use_fastboot_info = false;
+    auto hardcoded_tasks = tool.CollectTasks();
+    fp->should_use_fastboot_info = true;
+    auto fastboot_info_tasks = tool.CollectTasks();
+
+    auto is_non_flash_task = [](const auto& task) -> bool {
+        return task->AsFlashTask() == nullptr;
+    };
+
+    // remove non flash tasks for testing purposes
+    hardcoded_tasks.erase(
+            std::remove_if(hardcoded_tasks.begin(), hardcoded_tasks.end(), is_non_flash_task),
+            hardcoded_tasks.end());
+    fastboot_info_tasks.erase(std::remove_if(fastboot_info_tasks.begin(), fastboot_info_tasks.end(),
+                                             is_non_flash_task),
+                              fastboot_info_tasks.end());
+
+    if (!compareTaskList(fastboot_info_tasks, hardcoded_tasks)) {
+        std::cout << "\n\n---Hardcoded Task List---\n"
+                  << tasksToString(hardcoded_tasks) << "\n---Fastboot-Info Task List---\n"
+                  << tasksToString(fastboot_info_tasks);
+    }
+
+    ASSERT_TRUE(compareTaskList(fastboot_info_tasks, hardcoded_tasks));
+
+    ASSERT_TRUE(fastboot_info_tasks.size() >= hardcoded_tasks.size())
+            << "size of fastboot-info task list: " << fastboot_info_tasks.size()
+            << " size of hardcoded task list: " << hardcoded_tasks.size();
+}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 585eca2..2176233 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -577,7 +577,7 @@
  *
  * return code is processed based on input code
  */
-static Result<void> queue_fs_event(int code, bool userdata_remount) {
+static Result<void> queue_fs_event(int code) {
     if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
         SetProperty("ro.crypto.state", "unsupported");
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
@@ -591,27 +591,9 @@
         const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
         return reboot_into_recovery(options);
         /* If reboot worked, there is no return. */
-    } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
-        if (!FscryptInstallKeyring()) {
-            return Error() << "FscryptInstallKeyring() failed";
-        }
-        SetProperty("ro.crypto.state", "encrypted");
-
-        // Although encrypted, we have device key, so we do not need to
-        // do anything different from the nonencrypted case.
-        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
-        return {};
-    } else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
-        if (!FscryptInstallKeyring()) {
-            return Error() << "FscryptInstallKeyring() failed";
-        }
-        SetProperty("ro.crypto.state", "encrypted");
-
-        // Although encrypted, vold has already set the device up, so we do not need to
-        // do anything different from the nonencrypted case.
-        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
-        return {};
-    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
+    } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED ||
+               code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED ||
+               code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
         if (!FscryptInstallKeyring()) {
             return Error() << "FscryptInstallKeyring() failed";
         }
@@ -683,7 +665,7 @@
     if (queue_event) {
         /* queue_fs_event will queue event based on mount_fstab return code
          * and return processed return code*/
-        auto queue_fs_result = queue_fs_event(mount_fstab_result.code, false);
+        auto queue_fs_result = queue_fs_event(mount_fstab_result.code);
         if (!queue_fs_result.ok()) {
             return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
         }
@@ -1217,7 +1199,7 @@
                                          "/metadata/userspacereboot/mount_info.txt");
         trigger_shutdown("reboot,mount_userdata_failed");
     }
-    if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result.ok()) {
+    if (auto result = queue_fs_event(initial_mount_fstab_return_code); !result.ok()) {
         return Error() << "queue_fs_event() failed: " << result.error();
     }
     return {};
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index bff80c5..7fabbac 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -257,6 +257,16 @@
     return BootMode::NORMAL_MODE;
 }
 
+static std::unique_ptr<FirstStageMount> CreateFirstStageMount(const std::string& cmdline) {
+    auto ret = FirstStageMount::Create(cmdline);
+    if (ret.ok()) {
+        return std::move(*ret);
+    } else {
+        LOG(ERROR) << "Failed to create FirstStageMount : " << ret.error();
+        return nullptr;
+    }
+}
+
 int FirstStageMain(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
@@ -347,6 +357,18 @@
 
     LOG(INFO) << "init first stage started!";
 
+    // We only allow /vendor partition in debuggable Microdrod until it is verified during boot.
+    // TODO(b/285855436): remove this check.
+    if (IsMicrodroid()) {
+        bool mount_vendor =
+                cmdline.find("androidboot.microdroid.mount_vendor=1") != std::string::npos;
+        bool debuggable =
+                bootconfig.find("androidboot.microdroid.debuggable = \"1\"") != std::string::npos;
+        if (mount_vendor && !debuggable) {
+            LOG(FATAL) << "Attempted to mount /vendor partition for non-debuggable Microdroid VM";
+        }
+    }
+
     auto old_root_dir = std::unique_ptr<DIR, decltype(&closedir)>{opendir("/"), closedir};
     if (!old_root_dir) {
         PLOG(ERROR) << "Could not opendir(\"/\"), not freeing ramdisk";
@@ -381,12 +403,17 @@
                   << module_elapse_time.count() << " ms";
     }
 
+    std::unique_ptr<FirstStageMount> fsm;
+
     bool created_devices = false;
     if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
         if (!IsRecoveryMode()) {
-            created_devices = DoCreateDevices();
-            if (!created_devices) {
-                LOG(ERROR) << "Failed to create device nodes early";
+            fsm = CreateFirstStageMount(cmdline);
+            if (fsm) {
+                created_devices = fsm->DoCreateDevices();
+                if (!created_devices) {
+                    LOG(ERROR) << "Failed to create device nodes early";
+                }
             }
         }
         StartConsole(cmdline);
@@ -437,8 +464,23 @@
         SwitchRoot("/first_stage_ramdisk");
     }
 
-    if (!DoFirstStageMount(!created_devices)) {
-        LOG(FATAL) << "Failed to mount required partitions early ...";
+    if (IsRecoveryMode()) {
+        LOG(INFO) << "First stage mount skipped (recovery mode)";
+    } else {
+        if (!fsm) {
+            fsm = CreateFirstStageMount(cmdline);
+        }
+        if (!fsm) {
+            LOG(FATAL) << "FirstStageMount not available";
+        }
+
+        if (!created_devices && !fsm->DoCreateDevices()) {
+            LOG(FATAL) << "Failed to create devices required for first stage mount";
+        }
+
+        if (!fsm->DoFirstStageMount()) {
+            LOG(FATAL) << "Failed to mount required partitions early ...";
+        }
     }
 
     struct stat new_root_info;
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 07ce458..d0f68a8 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -76,21 +76,21 @@
 
 // Class Declarations
 // ------------------
-class FirstStageMount {
+class FirstStageMountVBootV2 : public FirstStageMount {
   public:
-    FirstStageMount(Fstab fstab);
-    virtual ~FirstStageMount() = default;
+    friend void SetInitAvbVersionInRecovery();
 
-    // The factory method to create a FirstStageMountVBootV2 instance.
-    static Result<std::unique_ptr<FirstStageMount>> Create();
-    bool DoCreateDevices();    // Creates devices and logical partitions from storage devices
-    bool DoFirstStageMount();  // Mounts fstab entries read from device tree.
+    FirstStageMountVBootV2(Fstab fstab);
+    virtual ~FirstStageMountVBootV2() = default;
+
+    bool DoCreateDevices() override;
+    bool DoFirstStageMount() override;
+
+  private:
     bool InitDevices();
-
-  protected:
     bool InitRequiredDevices(std::set<std::string> devices);
     bool CreateLogicalPartitions();
-    bool CreateSnapshotPartitions(android::snapshot::SnapshotManager* sm);
+    bool CreateSnapshotPartitions(SnapshotManager* sm);
     bool MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
                         Fstab::iterator* end = nullptr);
 
@@ -106,9 +106,10 @@
     // revocation check by DSU installation service.
     void CopyDsuAvbKeys();
 
-    // Pure virtual functions.
-    virtual bool GetDmVerityDevices(std::set<std::string>* devices) = 0;
-    virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
+    bool GetDmVerityDevices(std::set<std::string>* devices);
+    bool SetUpDmVerity(FstabEntry* fstab_entry);
+
+    bool InitAvbHandle();
 
     bool need_dm_verity_;
     bool dsu_not_on_userdata_ = false;
@@ -122,19 +123,6 @@
     // Reads all AVB keys before chroot into /system, as they might be used
     // later when mounting other partitions, e.g., /vendor and /product.
     std::map<std::string, std::vector<std::string>> preload_avb_key_blobs_;
-};
-
-class FirstStageMountVBootV2 : public FirstStageMount {
-  public:
-    friend void SetInitAvbVersionInRecovery();
-
-    FirstStageMountVBootV2(Fstab fstab);
-    ~FirstStageMountVBootV2() override = default;
-
-  protected:
-    bool GetDmVerityDevices(std::set<std::string>* devices) override;
-    bool SetUpDmVerity(FstabEntry* fstab_entry) override;
-    bool InitAvbHandle();
 
     std::vector<std::string> vbmeta_partitions_;
     AvbUniquePtr avb_handle_;
@@ -150,7 +138,7 @@
     return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
 }
 
-static Result<Fstab> ReadFirstStageFstab() {
+static Result<Fstab> ReadFirstStageFstabAndroid() {
     Fstab fstab;
     if (!ReadFstabFromDt(&fstab)) {
         if (ReadDefaultFstab(&fstab)) {
@@ -166,6 +154,24 @@
     return fstab;
 }
 
+// Note: this is a temporary solution to avoid blocking devs that depend on /vendor partition in
+// Microdroid. For the proper solution the /vendor fstab should probably be defined in the DT.
+// TODO(b/285855430): refactor this
+// TODO(b/285855436): verify key microdroid-vendor was signed with.
+// TODO(b/285855436): should be mounted on top of dm-verity device.
+static Result<Fstab> ReadFirstStageFstabMicrodroid(const std::string& cmdline) {
+    Fstab fstab;
+    if (!ReadDefaultFstab(&fstab)) {
+        return Error() << "failed to read fstab";
+    }
+    if (cmdline.find("androidboot.microdroid.mount_vendor=1") == std::string::npos) {
+        // We weren't asked to mount /vendor partition, filter it out from the fstab.
+        auto predicate = [](const auto& entry) { return entry.mount_point == "/vendor"; };
+        fstab.erase(std::remove_if(fstab.begin(), fstab.end(), predicate), fstab.end());
+    }
+    return fstab;
+}
+
 static bool GetRootEntry(FstabEntry* root_entry) {
     Fstab proc_mounts;
     if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
@@ -218,14 +224,13 @@
     return rollbacked;
 }
 
-// Class Definitions
-// -----------------
-FirstStageMount::FirstStageMount(Fstab fstab) : need_dm_verity_(false), fstab_(std::move(fstab)) {
-    super_partition_name_ = fs_mgr_get_super_partition_name();
-}
-
-Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
-    auto fstab = ReadFirstStageFstab();
+Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create(const std::string& cmdline) {
+    Result<Fstab> fstab;
+    if (IsMicrodroid()) {
+        fstab = ReadFirstStageFstabMicrodroid(cmdline);
+    } else {
+        fstab = ReadFirstStageFstabAndroid();
+    }
     if (!fstab.ok()) {
         return fstab.error();
     }
@@ -233,7 +238,7 @@
     return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
 }
 
-bool FirstStageMount::DoCreateDevices() {
+bool FirstStageMountVBootV2::DoCreateDevices() {
     if (!InitDevices()) return false;
 
     // Mount /metadata before creating logical partitions, since we need to
@@ -255,7 +260,7 @@
     return true;
 }
 
-bool FirstStageMount::DoFirstStageMount() {
+bool FirstStageMountVBootV2::DoFirstStageMount() {
     if (!IsDmLinearEnabled() && fstab_.empty()) {
         // Nothing to mount.
         LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
@@ -267,7 +272,7 @@
     return true;
 }
 
-bool FirstStageMount::InitDevices() {
+bool FirstStageMountVBootV2::InitDevices() {
     std::set<std::string> devices;
     GetSuperDeviceName(&devices);
 
@@ -288,14 +293,14 @@
     return true;
 }
 
-bool FirstStageMount::IsDmLinearEnabled() {
+bool FirstStageMountVBootV2::IsDmLinearEnabled() {
     for (const auto& entry : fstab_) {
         if (entry.fs_mgr_flags.logical) return true;
     }
     return false;
 }
 
-void FirstStageMount::GetSuperDeviceName(std::set<std::string>* devices) {
+void FirstStageMountVBootV2::GetSuperDeviceName(std::set<std::string>* devices) {
     // Add any additional devices required for dm-linear mappings.
     if (!IsDmLinearEnabled()) {
         return;
@@ -307,7 +312,7 @@
 // Creates devices with uevent->partition_name matching ones in the given set.
 // Found partitions will then be removed from it for the subsequent member
 // function to check which devices are NOT created.
-bool FirstStageMount::InitRequiredDevices(std::set<std::string> devices) {
+bool FirstStageMountVBootV2::InitRequiredDevices(std::set<std::string> devices) {
     if (!block_dev_init_.InitDeviceMapper()) {
         return false;
     }
@@ -317,7 +322,8 @@
     return block_dev_init_.InitDevices(std::move(devices));
 }
 
-bool FirstStageMount::InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata) {
+bool FirstStageMountVBootV2::InitDmLinearBackingDevices(
+        const android::fs_mgr::LpMetadata& metadata) {
     std::set<std::string> devices;
 
     auto partition_names = android::fs_mgr::GetBlockDevicePartitionNames(metadata);
@@ -334,7 +340,7 @@
     return InitRequiredDevices(std::move(devices));
 }
 
-bool FirstStageMount::CreateLogicalPartitions() {
+bool FirstStageMountVBootV2::CreateLogicalPartitions() {
     if (!IsDmLinearEnabled()) {
         return true;
     }
@@ -365,7 +371,7 @@
     return android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_path_);
 }
 
-bool FirstStageMount::CreateSnapshotPartitions(SnapshotManager* sm) {
+bool FirstStageMountVBootV2::CreateSnapshotPartitions(SnapshotManager* sm) {
     // When COW images are present for snapshots, they are stored on
     // the data partition.
     if (!InitRequiredDevices({"userdata"})) {
@@ -400,8 +406,8 @@
     return true;
 }
 
-bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
-                                     Fstab::iterator* end) {
+bool FirstStageMountVBootV2::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
+                                            Fstab::iterator* end) {
     // Sets end to begin + 1, so we can just return on failure below.
     if (end) {
         *end = begin + 1;
@@ -445,7 +451,7 @@
     return mounted;
 }
 
-void FirstStageMount::PreloadAvbKeys() {
+void FirstStageMountVBootV2::PreloadAvbKeys() {
     for (const auto& entry : fstab_) {
         // No need to cache the key content if it's empty, or is already cached.
         if (entry.avb_keys.empty() || preload_avb_key_blobs_.count(entry.avb_keys)) {
@@ -492,7 +498,7 @@
 // If system is in the fstab then we're not a system-as-root device, and in
 // this case, we mount system first then pivot to it.  From that point on,
 // we are effectively identical to a system-as-root device.
-bool FirstStageMount::TrySwitchSystemAsRoot() {
+bool FirstStageMountVBootV2::TrySwitchSystemAsRoot() {
     UseDsuIfPresent();
     // Preloading all AVB keys from the ramdisk before switching root to /system.
     PreloadAvbKeys();
@@ -521,7 +527,7 @@
     return true;
 }
 
-bool FirstStageMount::MountPartitions() {
+bool FirstStageMountVBootV2::MountPartitions() {
     if (!TrySwitchSystemAsRoot()) return false;
 
     if (!SkipMountingPartitions(&fstab_, true /* verbose */)) return false;
@@ -604,7 +610,7 @@
 // copy files to /metadata is NOT fatal, because it is auxiliary to perform
 // public key matching before booting into DSU images on next boot. The actual
 // public key matching will still be done on next boot to DSU.
-void FirstStageMount::CopyDsuAvbKeys() {
+void FirstStageMountVBootV2::CopyDsuAvbKeys() {
     std::error_code ec;
     // Removing existing keys in gsi::kDsuAvbKeyDir as they might be stale.
     std::filesystem::remove_all(gsi::kDsuAvbKeyDir, ec);
@@ -620,7 +626,7 @@
     }
 }
 
-void FirstStageMount::UseDsuIfPresent() {
+void FirstStageMountVBootV2::UseDsuIfPresent() {
     std::string error;
 
     if (!android::gsi::CanBootIntoGsi(&error)) {
@@ -657,10 +663,10 @@
     TransformFstabForDsu(&fstab_, active_dsu, dsu_partitions);
 }
 
-// First retrieve any vbmeta partitions from device tree (legacy) then read through the fstab
-// for any further vbmeta partitions.
 FirstStageMountVBootV2::FirstStageMountVBootV2(Fstab fstab)
-    : FirstStageMount(std::move(fstab)), avb_handle_(nullptr) {
+    : need_dm_verity_(false), fstab_(std::move(fstab)), avb_handle_(nullptr) {
+    super_partition_name_ = fs_mgr_get_super_partition_name();
+
     std::string device_tree_vbmeta_parts;
     read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts);
 
@@ -793,46 +799,13 @@
     return true;
 }
 
-// Public functions
-// ----------------
-// Creates devices and logical partitions from storage devices
-bool DoCreateDevices() {
-    auto fsm = FirstStageMount::Create();
-    if (!fsm.ok()) {
-        LOG(ERROR) << "Failed to create FirstStageMount: " << fsm.error();
-        return false;
-    }
-    return (*fsm)->DoCreateDevices();
-}
-
-// Mounts partitions specified by fstab in device tree.
-bool DoFirstStageMount(bool create_devices) {
-    // Skips first stage mount if we're in recovery mode.
-    if (IsRecoveryMode()) {
-        LOG(INFO) << "First stage mount skipped (recovery mode)";
-        return true;
-    }
-
-    auto fsm = FirstStageMount::Create();
-    if (!fsm.ok()) {
-        LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
-        return false;
-    }
-
-    if (create_devices) {
-        if (!(*fsm)->DoCreateDevices()) return false;
-    }
-
-    return (*fsm)->DoFirstStageMount();
-}
-
 void SetInitAvbVersionInRecovery() {
     if (!IsRecoveryMode()) {
         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not in recovery mode)";
         return;
     }
 
-    auto fstab = ReadFirstStageFstab();
+    auto fstab = ReadFirstStageFstabAndroid();
     if (!fstab.ok()) {
         LOG(ERROR) << fstab.error();
         return;
diff --git a/init/first_stage_mount.h b/init/first_stage_mount.h
index 2f4e663..54501d8 100644
--- a/init/first_stage_mount.h
+++ b/init/first_stage_mount.h
@@ -16,11 +16,28 @@
 
 #pragma once
 
+#include <memory>
+
+#include "result.h"
+
 namespace android {
 namespace init {
 
-bool DoCreateDevices();
-bool DoFirstStageMount(bool create_devices);
+class FirstStageMount {
+  public:
+    virtual ~FirstStageMount() = default;
+
+    // The factory method to create a FirstStageMount instance.
+    static Result<std::unique_ptr<FirstStageMount>> Create(const std::string& cmdline);
+    // Creates devices and logical partitions from storage devices
+    virtual bool DoCreateDevices() = 0;
+    // Mounts fstab entries read from device tree.
+    virtual bool DoFirstStageMount() = 0;
+
+  protected:
+    FirstStageMount() = default;
+};
+
 void SetInitAvbVersionInRecovery();
 
 }  // namespace init
diff --git a/libbinderwrapper/Android.bp b/libbinderwrapper/Android.bp
deleted file mode 100644
index 75f43ee..0000000
--- a/libbinderwrapper/Android.bp
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_defaults {
-    name: "libbinderwrapper_defaults",
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-
-        // for libchrome
-        "-Wno-sign-promo",
-    ],
-    export_include_dirs: ["include"],
-    shared_libs: [
-        "libbinder",
-        "libchrome",
-        "libutils",
-    ],
-}
-
-// libbinderwrapper shared library
-// ========================================================
-cc_library_shared {
-    name: "libbinderwrapper",
-    defaults: ["libbinderwrapper_defaults"],
-    vendor_available: true,
-
-    srcs: [
-        "binder_wrapper.cc",
-        "real_binder_wrapper.cc",
-    ],
-}
-
-// libbinderwrapper_test_support static library
-// ========================================================
-cc_library_static {
-    name: "libbinderwrapper_test_support",
-    defaults: ["libbinderwrapper_defaults"],
-
-    static_libs: ["libgtest"],
-    shared_libs: ["libbinderwrapper"],
-
-    srcs: [
-        "binder_test_base.cc",
-        "stub_binder_wrapper.cc",
-    ],
-}
diff --git a/libbinderwrapper/binder_test_base.cc b/libbinderwrapper/binder_test_base.cc
deleted file mode 100644
index af93a04..0000000
--- a/libbinderwrapper/binder_test_base.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binderwrapper/binder_test_base.h>
-
-#include <binderwrapper/binder_wrapper.h>
-#include <binderwrapper/stub_binder_wrapper.h>
-
-namespace android {
-
-BinderTestBase::BinderTestBase() : binder_wrapper_(new StubBinderWrapper()) {
-  // Pass ownership.
-  BinderWrapper::InitForTesting(binder_wrapper_);
-}
-
-BinderTestBase::~BinderTestBase() {
-  BinderWrapper::Destroy();
-}
-
-}  // namespace android
diff --git a/libbinderwrapper/binder_wrapper.cc b/libbinderwrapper/binder_wrapper.cc
deleted file mode 100644
index ca9c1df..0000000
--- a/libbinderwrapper/binder_wrapper.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binderwrapper/binder_wrapper.h>
-
-#include <base/logging.h>
-
-#include "real_binder_wrapper.h"
-
-namespace android {
-
-// Singleton instance.
-BinderWrapper* BinderWrapper::instance_ = nullptr;
-
-// static
-void BinderWrapper::Create() {
-  CHECK(!instance_) << "Already initialized; missing call to Destroy()?";
-  instance_ = new RealBinderWrapper();
-}
-
-// static
-void BinderWrapper::InitForTesting(BinderWrapper* wrapper) {
-  CHECK(!instance_) << "Already initialized; missing call to Destroy()?";
-  instance_ = wrapper;
-}
-
-// static
-void BinderWrapper::Destroy() {
-  CHECK(instance_) << "Not initialized; missing call to Create()?";
-  delete instance_;
-  instance_ = nullptr;
-}
-
-// static
-BinderWrapper* BinderWrapper::Get() {
-  CHECK(instance_) << "Not initialized; missing call to Create()?";
-  return instance_;
-}
-
-// static
-BinderWrapper* BinderWrapper::GetOrCreateInstance() {
-  if (!instance_)
-    instance_ = new RealBinderWrapper();
-  return instance_;
-}
-
-}  // namespace android
diff --git a/libbinderwrapper/include/binderwrapper/binder_test_base.h b/libbinderwrapper/include/binderwrapper/binder_test_base.h
deleted file mode 100644
index 06543de..0000000
--- a/libbinderwrapper/include/binderwrapper/binder_test_base.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_
-#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_
-
-#include <base/macros.h>
-#include <gtest/gtest.h>
-
-namespace android {
-
-class StubBinderWrapper;
-
-// Class that can be inherited from (or aliased via typedef/using) when writing
-// tests that use StubBinderManager.
-class BinderTestBase : public ::testing::Test {
- public:
-  BinderTestBase();
-  ~BinderTestBase() override;
-
-  StubBinderWrapper* binder_wrapper() { return binder_wrapper_; }
-
- protected:
-  StubBinderWrapper* binder_wrapper_;  // Not owned.
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BinderTestBase);
-};
-
-}  // namespace android
-
-#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_
diff --git a/libbinderwrapper/include/binderwrapper/binder_wrapper.h b/libbinderwrapper/include/binderwrapper/binder_wrapper.h
deleted file mode 100644
index a104bff..0000000
--- a/libbinderwrapper/include/binderwrapper/binder_wrapper.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_
-#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_
-
-#include <sys/types.h>
-
-#include <string>
-
-#include <base/callback.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-
-class BBinder;
-class IBinder;
-
-// Wraps libbinder to make it testable.
-// NOTE: Static methods of this class are not thread-safe.
-class BinderWrapper {
- public:
-  virtual ~BinderWrapper() {}
-
-  // Creates and initializes the singleton (using a wrapper that communicates
-  // with the real binder system).
-  static void Create();
-
-  // Initializes |wrapper| as the singleton, taking ownership of it. Tests that
-  // want to inject their own wrappers should call this instead of Create().
-  static void InitForTesting(BinderWrapper* wrapper);
-
-  // Destroys the singleton. Must be called before calling Create() or
-  // InitForTesting() a second time.
-  static void Destroy();
-
-  // Returns the singleton instance previously created by Create() or set by
-  // InitForTesting().
-  static BinderWrapper* Get();
-
-  // Returns the singleton instance if it was previously created by Create() or
-  // set by InitForTesting(), or creates a new one by calling Create().
-  static BinderWrapper* GetOrCreateInstance();
-
-  // Gets the binder for communicating with the service identified by
-  // |service_name|, returning null immediately if it doesn't exist.
-  virtual sp<IBinder> GetService(const std::string& service_name) = 0;
-
-  // Registers |binder| as |service_name| with the service manager.
-  virtual bool RegisterService(const std::string& service_name,
-                               const sp<IBinder>& binder) = 0;
-
-  // Creates a local binder object.
-  virtual sp<BBinder> CreateLocalBinder() = 0;
-
-  // Registers |callback| to be invoked when |binder| dies. If another callback
-  // is currently registered for |binder|, it will be replaced.
-  virtual bool RegisterForDeathNotifications(
-      const sp<IBinder>& binder,
-      const ::base::Closure& callback) = 0;
-
-  // Unregisters the callback, if any, for |binder|.
-  virtual bool UnregisterForDeathNotifications(const sp<IBinder>& binder) = 0;
-
-  // When called while in a transaction, returns the caller's UID or PID.
-  virtual uid_t GetCallingUid() = 0;
-  virtual pid_t GetCallingPid() = 0;
-
- private:
-  static BinderWrapper* instance_;
-};
-
-}  // namespace android
-
-#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_
diff --git a/libbinderwrapper/include/binderwrapper/stub_binder_wrapper.h b/libbinderwrapper/include/binderwrapper/stub_binder_wrapper.h
deleted file mode 100644
index 9d4578e..0000000
--- a/libbinderwrapper/include/binderwrapper/stub_binder_wrapper.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_
-#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include <base/macros.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binderwrapper/binder_wrapper.h>
-
-namespace android {
-
-// Stub implementation of BinderWrapper for testing.
-//
-// Example usage:
-//
-// First, assuming a base IFoo binder interface, create a stub class that
-// derives from BnFoo to implement the receiver side of the communication:
-//
-//   class StubFoo : public BnFoo {
-//    public:
-//     ...
-//     status_t doSomething(int arg) override {
-//       // e.g. save passed-in value for later inspection by tests.
-//       return OK;
-//     }
-//   };
-//
-// Next, from your test code, inject a StubBinderManager either directly or by
-// inheriting from the BinderTestBase class:
-//
-//   StubBinderWrapper* wrapper = new StubBinderWrapper();
-//   BinderWrapper::InitForTesting(wrapper);  // Takes ownership.
-//
-// Also from your test, create a StubFoo and register it with the wrapper:
-//
-//   StubFoo* foo = new StubFoo();
-//   sp<IBinder> binder(foo);
-//   wrapper->SetBinderForService("foo", binder);
-//
-// The code being tested can now use the wrapper to get the stub and call it:
-//
-//   sp<IBinder> binder = BinderWrapper::Get()->GetService("foo");
-//   CHECK(binder.get());
-//   sp<IFoo> foo = interface_cast<IFoo>(binder);
-//   CHECK_EQ(foo->doSomething(3), OK);
-//
-// To create a local BBinder object, production code can call
-// CreateLocalBinder(). Then, a test can get the BBinder's address via
-// local_binders() to check that they're passed as expected in binder calls.
-//
-class StubBinderWrapper : public BinderWrapper {
- public:
-  StubBinderWrapper();
-  ~StubBinderWrapper() override;
-
-  const std::vector<sp<BBinder>>& local_binders() const {
-    return local_binders_;
-  }
-  void clear_local_binders() { local_binders_.clear(); }
-
-  void set_calling_uid(uid_t uid) { calling_uid_ = uid; }
-  void set_calling_pid(pid_t pid) { calling_pid_ = pid; }
-
-  // Sets the binder to return when |service_name| is passed to GetService() or
-  // WaitForService().
-  void SetBinderForService(const std::string& service_name,
-                           const sp<IBinder>& binder);
-
-  // Returns the binder previously registered for |service_name| via
-  // RegisterService(), or null if the service hasn't been registered.
-  sp<IBinder> GetRegisteredService(const std::string& service_name) const;
-
-  // Run the calback in |death_callbacks_| corresponding to |binder|.
-  void NotifyAboutBinderDeath(const sp<IBinder>& binder);
-
-  // BinderWrapper:
-  sp<IBinder> GetService(const std::string& service_name) override;
-  bool RegisterService(const std::string& service_name,
-                       const sp<IBinder>& binder) override;
-  sp<BBinder> CreateLocalBinder() override;
-  bool RegisterForDeathNotifications(const sp<IBinder>& binder,
-                                     const ::base::Closure& callback) override;
-  bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override;
-  uid_t GetCallingUid() override;
-  pid_t GetCallingPid() override;
-
- private:
-  using ServiceMap = std::map<std::string, sp<IBinder>>;
-
-  // Map from service name to associated binder handle. Used by GetService() and
-  // WaitForService().
-  ServiceMap services_to_return_;
-
-  // Map from service name to associated binder handle. Updated by
-  // RegisterService().
-  ServiceMap registered_services_;
-
-  // Local binders returned by CreateLocalBinder().
-  std::vector<sp<BBinder>> local_binders_;
-
-  // Map from binder handle to the callback that should be invoked on binder
-  // death.
-  std::map<sp<IBinder>, ::base::Closure> death_callbacks_;
-
-  // Values to return from GetCallingUid() and GetCallingPid();
-  uid_t calling_uid_;
-  pid_t calling_pid_;
-
-  DISALLOW_COPY_AND_ASSIGN(StubBinderWrapper);
-};
-
-}  // namespace android
-
-#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_
diff --git a/libbinderwrapper/real_binder_wrapper.cc b/libbinderwrapper/real_binder_wrapper.cc
deleted file mode 100644
index f93f183..0000000
--- a/libbinderwrapper/real_binder_wrapper.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "real_binder_wrapper.h"
-
-#include <base/logging.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-namespace android {
-
-// Class that handles binder death notifications. libbinder wants the recipient
-// to be wrapped in sp<>, so registering RealBinderWrapper as a recipient would
-// be awkward.
-class RealBinderWrapper::DeathRecipient : public IBinder::DeathRecipient {
- public:
-  explicit DeathRecipient(const ::base::Closure& callback)
-      : callback_(callback) {}
-  ~DeathRecipient() = default;
-
-  // IBinder::DeathRecipient:
-  void binderDied(const wp<IBinder>& who) override {
-    callback_.Run();
-  }
-
- private:
-  // Callback to run in response to binder death.
-  ::base::Closure callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeathRecipient);
-};
-
-RealBinderWrapper::RealBinderWrapper() = default;
-
-RealBinderWrapper::~RealBinderWrapper() = default;
-
-sp<IBinder> RealBinderWrapper::GetService(const std::string& service_name) {
-  sp<IServiceManager> service_manager = defaultServiceManager();
-  if (!service_manager.get()) {
-    LOG(ERROR) << "Unable to get service manager";
-    return sp<IBinder>();
-  }
-  sp<IBinder> binder =
-      service_manager->checkService(String16(service_name.c_str()));
-  if (!binder.get())
-    LOG(ERROR) << "Unable to get \"" << service_name << "\" service";
-  return binder;
-}
-
-bool RealBinderWrapper::RegisterService(const std::string& service_name,
-                                        const sp<IBinder>& binder) {
-  sp<IServiceManager> service_manager = defaultServiceManager();
-  if (!service_manager.get()) {
-    LOG(ERROR) << "Unable to get service manager";
-    return false;
-  }
-  status_t status = defaultServiceManager()->addService(
-      String16(service_name.c_str()), binder);
-  if (status != OK) {
-    LOG(ERROR) << "Failed to register \"" << service_name << "\" with service "
-               << "manager";
-    return false;
-  }
-  return true;
-}
-
-sp<BBinder> RealBinderWrapper::CreateLocalBinder() {
-  return sp<BBinder>(new BBinder());
-}
-
-bool RealBinderWrapper::RegisterForDeathNotifications(
-    const sp<IBinder>& binder,
-    const ::base::Closure& callback) {
-  sp<DeathRecipient> recipient(new DeathRecipient(callback));
-  if (binder->linkToDeath(recipient) != OK) {
-    LOG(ERROR) << "Failed to register for death notifications on "
-               << binder.get();
-    return false;
-  }
-  death_recipients_[binder] = recipient;
-  return true;
-}
-
-bool RealBinderWrapper::UnregisterForDeathNotifications(
-    const sp<IBinder>& binder) {
-  auto it = death_recipients_.find(binder);
-  if (it == death_recipients_.end()) {
-    LOG(ERROR) << "Not registered for death notifications on " << binder.get();
-    return false;
-  }
-  if (binder->unlinkToDeath(it->second) != OK) {
-    LOG(ERROR) << "Failed to unregister for death notifications on "
-               << binder.get();
-    return false;
-  }
-  death_recipients_.erase(it);
-  return true;
-}
-
-uid_t RealBinderWrapper::GetCallingUid() {
-  return IPCThreadState::self()->getCallingUid();
-}
-
-pid_t RealBinderWrapper::GetCallingPid() {
-  return IPCThreadState::self()->getCallingPid();
-}
-
-}  // namespace android
diff --git a/libbinderwrapper/real_binder_wrapper.h b/libbinderwrapper/real_binder_wrapper.h
deleted file mode 100644
index fa05383..0000000
--- a/libbinderwrapper/real_binder_wrapper.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SYSTEM_CORE_LIBBINDERWRAPPER_REAL_BINDER_WRAPPER_H_
-#define SYSTEM_CORE_LIBBINDERWRAPPER_REAL_BINDER_WRAPPER_H_
-
-#include <map>
-
-#include <base/macros.h>
-#include <binderwrapper/binder_wrapper.h>
-
-namespace android {
-
-class IBinder;
-
-// Real implementation of BinderWrapper.
-class RealBinderWrapper : public BinderWrapper {
- public:
-  RealBinderWrapper();
-  ~RealBinderWrapper() override;
-
-  // BinderWrapper:
-  sp<IBinder> GetService(const std::string& service_name) override;
-  bool RegisterService(const std::string& service_name,
-                       const sp<IBinder>& binder) override;
-  sp<BBinder> CreateLocalBinder() override;
-  bool RegisterForDeathNotifications(const sp<IBinder>& binder,
-                                     const ::base::Closure& callback) override;
-  bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override;
-  uid_t GetCallingUid() override;
-  pid_t GetCallingPid() override;
-
- private:
-  class DeathRecipient;
-
-  // Map from binder handle to object that should be notified of the binder's
-  // death.
-  std::map<sp<IBinder>, sp<DeathRecipient>> death_recipients_;
-
-  DISALLOW_COPY_AND_ASSIGN(RealBinderWrapper);
-};
-
-}  // namespace android
-
-#endif  // SYSTEM_CORE_LIBBINDER_WRAPPER_REAL_BINDER_WRAPPER_H_
diff --git a/libbinderwrapper/stub_binder_wrapper.cc b/libbinderwrapper/stub_binder_wrapper.cc
deleted file mode 100644
index 8e75f62..0000000
--- a/libbinderwrapper/stub_binder_wrapper.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binderwrapper/stub_binder_wrapper.h>
-
-#include <base/logging.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-
-namespace android {
-
-StubBinderWrapper::StubBinderWrapper()
-    : calling_uid_(-1),
-      calling_pid_(-1) {}
-
-StubBinderWrapper::~StubBinderWrapper() = default;
-
-void StubBinderWrapper::SetBinderForService(const std::string& service_name,
-                                            const sp<IBinder>& binder) {
-  services_to_return_[service_name] = binder;
-}
-
-sp<IBinder> StubBinderWrapper::GetRegisteredService(
-    const std::string& service_name) const {
-  const auto it = registered_services_.find(service_name);
-  return it != registered_services_.end() ? it->second : sp<IBinder>();
-}
-
-void StubBinderWrapper::NotifyAboutBinderDeath(const sp<IBinder>& binder) {
-  const auto it = death_callbacks_.find(binder);
-  if (it != death_callbacks_.end())
-    it->second.Run();
-}
-
-sp<IBinder> StubBinderWrapper::GetService(const std::string& service_name) {
-  const auto it = services_to_return_.find(service_name);
-  return it != services_to_return_.end() ? it->second : sp<IBinder>();
-}
-
-bool StubBinderWrapper::RegisterService(const std::string& service_name,
-                                        const sp<IBinder>& binder) {
-  registered_services_[service_name] = binder;
-  return true;
-}
-
-sp<BBinder> StubBinderWrapper::CreateLocalBinder() {
-  sp<BBinder> binder(new BBinder());
-  local_binders_.push_back(binder);
-  return binder;
-}
-
-bool StubBinderWrapper::RegisterForDeathNotifications(
-    const sp<IBinder>& binder,
-    const ::base::Closure& callback) {
-  death_callbacks_[binder] = callback;
-  return true;
-}
-
-bool StubBinderWrapper::UnregisterForDeathNotifications(
-    const sp<IBinder>& binder) {
-  death_callbacks_.erase(binder);
-  return true;
-}
-
-uid_t StubBinderWrapper::GetCallingUid() {
-  return calling_uid_;
-}
-
-pid_t StubBinderWrapper::GetCallingPid() {
-  return calling_pid_;
-}
-
-}  // namespace android
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index cd9db54..55bbe46 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -150,15 +150,10 @@
 }
 
 NetlinkEvent::~NetlinkEvent() {
-    int i;
-    if (mPath)
-        free(mPath);
-    if (mSubsystem)
-        free(mSubsystem);
-    for (i = 0; i < NL_PARAMS_MAX; i++) {
-        if (!mParams[i])
-            break;
-        free(mParams[i]);
+    free(mPath);
+    free(mSubsystem);
+    for (auto param : mParams) {
+        free(param);
     }
 }
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a8b78d5..4f3959f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -533,7 +533,7 @@
     # Should be before netd, but after apex, properties and logging is available.
     trigger load_bpf_programs
 
-    # Now we can start zygote for devices with file based encryption
+    # Now we can start zygote.
     trigger zygote-start
 
     # Remove a file to wake up anything waiting for firmware.
@@ -1056,25 +1056,7 @@
 
 # It is recommended to put unnecessary data/ initialization from post-fs-data
 # to start-zygote in device's init.rc to unblock zygote start.
-on zygote-start && property:ro.crypto.state=unencrypted
-    wait_for_prop odsign.verification.done 1
-    # A/B update verifier that marks a successful boot.
-    exec_start update_verifier_nonencrypted
-    start statsd
-    start netd
-    start zygote
-    start zygote_secondary
-
-on zygote-start && property:ro.crypto.state=unsupported
-    wait_for_prop odsign.verification.done 1
-    # A/B update verifier that marks a successful boot.
-    exec_start update_verifier_nonencrypted
-    start statsd
-    start netd
-    start zygote
-    start zygote_secondary
-
-on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
+on zygote-start
     wait_for_prop odsign.verification.done 1
     # A/B update verifier that marks a successful boot.
     exec_start update_verifier_nonencrypted