Merge "Add fs_config entry for *.rc files." into main
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 77d4a07..1c1fb8a 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -449,7 +449,16 @@
 
   if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TLS, &pt_iov) != 0) {
     PLOG(ERROR) << "failed to read thread register for thread " << tid;
+    return false;
   }
+#elif defined(__riscv)
+  struct user_regs_struct regs;
+  struct iovec pt_iov = {.iov_base = &regs, .iov_len = sizeof(regs)};
+  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) != 0) {
+    PLOG(ERROR) << "failed to read thread register for thread " << tid;
+    return false;
+  }
+  base = reinterpret_cast<uintptr_t>(regs.tp);
 #else
   // TODO(b/339287219): Add case for Riscv host.
   return false;
diff --git a/debuggerd/test_permissive_mte/AndroidTest.xml b/debuggerd/test_permissive_mte/AndroidTest.xml
index bd3d018..db5f5b8 100644
--- a/debuggerd/test_permissive_mte/AndroidTest.xml
+++ b/debuggerd/test_permissive_mte/AndroidTest.xml
@@ -17,8 +17,6 @@
     <option name="test-suite-tag" value="init_test_upgrade_mte" />
     <option name="test-suite-tag" value="apct" />
 
-    <!-- For tombstone inspection. -->
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
       <option name="cleanup" value="true" />
       <option name="push" value="mte_crash->/data/local/tmp/mte_crash" />
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 914b4a6..402eb82 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -503,6 +503,8 @@
             enabled: false,
         },
     },
+    stl: "libc++_static",
+    static_executable: true,
 }
 
 python_library_host {
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 076a918..d04c9c1 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -103,7 +103,7 @@
     // The old partition size (if none existed, this will be zero).
     uint64 old_partition_size = 10;
 
-    // Compression algorithm (none, gz, lz4, zstd, or brotli).
+    // Compression algorithm (none, lz4, zstd).
     string compression_algorithm = 11;
 
     // Estimated COW size from OTA manifest.
@@ -120,6 +120,18 @@
 
     // Max bytes to be compressed at once (4k, 8k, 16k, 32k, 64k, 128k)
     uint64 compression_factor = 16;
+
+    // Default value is 32, can be set lower for low mem devices
+    uint32 read_ahead_size = 17;
+
+    // Enable direct reads on source device
+    bool o_direct = 18;
+
+    // Blocks size to be verified at once
+    uint64 verify_block_size = 19;
+
+    // Default value is 2, configures threads to do verification phase
+    uint32 num_verify_threads = 20;
 }
 
 // Next: 8
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
index 21dc666..635a38c 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_compress.h
@@ -17,6 +17,8 @@
 #pragma once
 
 #include <memory>
+#include <vector>
+
 #include "libsnapshot/cow_format.h"
 
 namespace android {
@@ -50,4 +52,4 @@
     const uint32_t block_size_;
 };
 }  // namespace snapshot
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 3f49c69..3389f58 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -19,6 +19,7 @@
 #include <memory>
 #include <optional>
 #include <unordered_map>
+#include <vector>
 
 #include <android-base/unique_fd.h>
 #include <libsnapshot/cow_format.h>
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.h b/fs_mgr/libsnapshot/partition_cow_creator.h
index cbd664f..a75d993 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.h
+++ b/fs_mgr/libsnapshot/partition_cow_creator.h
@@ -60,6 +60,7 @@
     bool using_snapuserd = false;
     std::string compression_algorithm;
     uint64_t compression_factor;
+    uint32_t read_ahead_size;
 
     // True if multi-threaded compression should be enabled
     bool enable_threading;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 7ca53ad..8620620 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -101,8 +101,7 @@
  * time, they could use O_DIRECT functionality wherein the I/O to the source
  * block device will be O_DIRECT.
  */
-static constexpr auto kCowReadAheadSizeKb = 32;
-static constexpr auto kSourceReadAheadSizeKb = 32;
+static constexpr auto kReadAheadSizeKb = 32;
 
 // Note: IImageManager is an incomplete type in the header, so the default
 // destructor doesn't work.
@@ -418,6 +417,7 @@
     status->set_using_snapuserd(cow_creator->using_snapuserd);
     status->set_compression_algorithm(cow_creator->compression_algorithm);
     status->set_compression_factor(cow_creator->compression_factor);
+    status->set_read_ahead_size(cow_creator->read_ahead_size);
     if (cow_creator->enable_threading) {
         status->set_enable_threading(cow_creator->enable_threading);
     }
@@ -1142,8 +1142,8 @@
     return result;
 }
 
-auto SnapshotManager::CheckMergeState(LockedFile* lock, const std::function<bool()>& before_cancel)
-        -> MergeResult {
+auto SnapshotManager::CheckMergeState(LockedFile* lock,
+                                      const std::function<bool()>& before_cancel) -> MergeResult {
     SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock);
     switch (update_status.state()) {
         case UpdateState::None:
@@ -1765,9 +1765,8 @@
                                base_path_merge;
                 snapuserd_argv->emplace_back(std::move(message));
             }
-
-            SetReadAheadSize(cow_image_device, kCowReadAheadSizeKb);
-            SetReadAheadSize(source_device, kSourceReadAheadSizeKb);
+            SetReadAheadSize(cow_image_device, snapshot_status.read_ahead_size());
+            SetReadAheadSize(source_device, snapshot_status.read_ahead_size());
 
             // Do not attempt to connect to the new snapuserd yet, it hasn't
             // been started. We do however want to wait for the misc device
@@ -2852,8 +2851,8 @@
     return true;
 }
 
-auto SnapshotManager::OpenFile(const std::string& file, int lock_flags)
-        -> std::unique_ptr<LockedFile> {
+auto SnapshotManager::OpenFile(const std::string& file,
+                               int lock_flags) -> std::unique_ptr<LockedFile> {
     unique_fd fd(open(file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
     if (fd < 0) {
         PLOG(ERROR) << "Open failed: " << file;
@@ -3309,19 +3308,19 @@
         LOG(INFO) << "using compression algorithm: " << compression_algorithm
                   << ", max compressible block size: " << compression_factor;
     }
-
-    PartitionCowCreator cow_creator{
-            .target_metadata = target_metadata.get(),
-            .target_suffix = target_suffix,
-            .target_partition = nullptr,
-            .current_metadata = current_metadata.get(),
-            .current_suffix = current_suffix,
-            .update = nullptr,
-            .extra_extents = {},
-            .using_snapuserd = using_snapuserd,
-            .compression_algorithm = compression_algorithm,
-            .compression_factor = compression_factor,
-    };
+    auto read_ahead_size =
+            android::base::GetUintProperty<uint>("ro.virtual_ab.read_ahead_size", kReadAheadSizeKb);
+    PartitionCowCreator cow_creator{.target_metadata = target_metadata.get(),
+                                    .target_suffix = target_suffix,
+                                    .target_partition = nullptr,
+                                    .current_metadata = current_metadata.get(),
+                                    .current_suffix = current_suffix,
+                                    .update = nullptr,
+                                    .extra_extents = {},
+                                    .using_snapuserd = using_snapuserd,
+                                    .compression_algorithm = compression_algorithm,
+                                    .compression_factor = compression_factor,
+                                    .read_ahead_size = read_ahead_size};
 
     if (dap_metadata.vabc_feature_set().has_threaded()) {
         cow_creator.enable_threading = dap_metadata.vabc_feature_set().threaded();
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.cpp
index 711e704..ea11f0e 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.cpp
@@ -19,6 +19,7 @@
 
 #include <android-base/logging.h>
 
+#include "android-base/properties.h"
 #include "merge_worker.h"
 #include "read_worker.h"
 #include "snapuserd_core.h"
@@ -235,8 +236,10 @@
 
         LOG(INFO) << "MonitorMerge: active-merge-threads: " << active_merge_threads_;
         {
+            auto num_merge_threads = android::base::GetUintProperty<uint>(
+                    "ro.virtual_ab.num_merge_threads", kMaxMergeThreads);
             std::lock_guard<std::mutex> lock(lock_);
-            while (active_merge_threads_ < kMaxMergeThreads && merge_handlers_.size() > 0) {
+            while (active_merge_threads_ < num_merge_threads && merge_handlers_.size() > 0) {
                 auto handler = merge_handlers_.front();
                 merge_handlers_.pop();
 
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_server.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_server.h
index 3013c47..d9cf97f 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_server.h
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_server.h
@@ -39,7 +39,7 @@
 namespace snapshot {
 
 static constexpr uint32_t kMaxPacketSize = 512;
-static constexpr uint8_t kMaxMergeThreads = 2;
+
 static constexpr char kBootSnapshotsWithoutSlotSwitch[] =
         "/metadata/ota/snapshot-boot-without-slot-switch";
 
diff --git a/init/devices.cpp b/init/devices.cpp
index e76786a..5560c20 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -25,6 +25,7 @@
 #include <filesystem>
 #include <memory>
 #include <string>
+#include <string_view>
 #include <thread>
 
 #include <android-base/chrono_utils.h>
@@ -377,8 +378,8 @@
 
     if (FindPlatformDevice(uevent.path, &device)) {
         // Skip /devices/platform or /devices/ if present
-        static const std::string devices_platform_prefix = "/devices/platform/";
-        static const std::string devices_prefix = "/devices/";
+        static constexpr std::string_view devices_platform_prefix = "/devices/platform/";
+        static constexpr std::string_view devices_prefix = "/devices/";
 
         if (StartsWith(device, devices_platform_prefix)) {
             device = device.substr(devices_platform_prefix.length());
@@ -434,6 +435,7 @@
     if (ReadFileToString("/sys/class/block/" + uevent.device_name + "/queue/zoned", &model) &&
         !StartsWith(model, "none")) {
         links.emplace_back("/dev/block/by-name/zoned_device");
+        links.emplace_back("/dev/sys/block/by-name/zoned_device");
     }
 
     auto last_slash = uevent.path.rfind('/');
@@ -482,11 +484,21 @@
     // event.
     if (action == "add" || (action == "change" && StartsWith(devpath, "/dev/block/dm-"))) {
         for (const auto& link : links) {
+            std::string target;
+            if (StartsWith(link, "/dev/block/")) {
+                target = devpath;
+            } else if (StartsWith(link, "/dev/sys/block/")) {
+                target = "/sys/class/block/" + Basename(devpath);
+            } else {
+                LOG(ERROR) << "Unrecognized link type: " << link;
+                continue;
+            }
+
             if (!mkdir_recursive(Dirname(link), 0755)) {
                 PLOG(ERROR) << "Failed to create directory " << Dirname(link);
             }
 
-            if (symlink(devpath.c_str(), link.c_str())) {
+            if (symlink(target.c_str(), link.c_str())) {
                 if (errno != EEXIST) {
                     PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link;
                 } else if (std::string link_path;
diff --git a/init/devices.h b/init/devices.h
index 44ce2a9..6da1232 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -127,9 +127,6 @@
     virtual ~DeviceHandler() = default;
 
     void HandleUevent(const Uevent& uevent) override;
-    void ColdbootDone() override;
-
-    std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
 
     // `androidboot.partition_map` allows associating a partition name for a raw block device
     // through a comma separated and semicolon deliminated list. For example,
@@ -138,11 +135,13 @@
     static std::string GetPartitionNameForDevice(const std::string& device);
 
   private:
+    void ColdbootDone() override;
     bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
     std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
         const std::string& path, const std::vector<std::string>& links) const;
     void MakeDevice(const std::string& path, bool block, int major, int minor,
                     const std::vector<std::string>& links) const;
+    std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
     void HandleDevice(const std::string& action, const std::string& devpath, bool block, int major,
                       int minor, const std::vector<std::string>& links) const;
     void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 3c012fe..01957ef 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -264,8 +264,9 @@
     return uevent.firmware;
 }
 
-void FirmwareHandler::ProcessFirmwareEvent(const std::string& root,
+void FirmwareHandler::ProcessFirmwareEvent(const std::string& path,
                                            const std::string& firmware) const {
+    std::string root = "/sys" + path;
     std::string loading = root + "/loading";
     std::string data = root + "/data";
 
@@ -296,6 +297,7 @@
                                                     ", fstat failed: " + strerror(errno));
             return false;
         }
+        LOG(INFO) << "found " << file << " for " << path;
         LoadFirmware(firmware, root, fw_fd.get(), sb.st_size, loading_fd.get(), data_fd.get());
         return true;
     };
@@ -362,7 +364,7 @@
     if (pid == 0) {
         Timer t;
         auto firmware = GetFirmwarePath(uevent);
-        ProcessFirmwareEvent("/sys" + uevent.path, firmware);
+        ProcessFirmwareEvent(uevent.path, firmware);
         LOG(INFO) << "loading " << uevent.path << " took " << t;
         _exit(EXIT_SUCCESS);
     }
diff --git a/init/firmware_handler.h b/init/firmware_handler.h
index d2f7347..fceb392 100644
--- a/init/firmware_handler.h
+++ b/init/firmware_handler.h
@@ -57,7 +57,7 @@
     Result<std::string> RunExternalHandler(const std::string& handler, uid_t uid, gid_t gid,
                                            const Uevent& uevent) const;
     std::string GetFirmwarePath(const Uevent& uevent) const;
-    void ProcessFirmwareEvent(const std::string& root, const std::string& firmware) const;
+    void ProcessFirmwareEvent(const std::string& path, const std::string& firmware) const;
     bool ForEachFirmwareDirectory(std::function<bool(const std::string&)> handler) const;
 
     std::vector<std::string> firmware_directories_;
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 7e8513b..5088273 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -630,7 +630,7 @@
 
     ASSERT_TRUE(parser.ParseConfig(tf.path));
 
-    if (GetIntProperty("ro.vendor.api_level", 0) > __ANDROID_API_U__) {
+    if (GetIntProperty("ro.vendor.api_level", 0) > 202404) {
         ASSERT_EQ(1u, parser.parse_error_count());
     } else {
         ASSERT_EQ(0u, parser.parse_error_count());
diff --git a/init/security.cpp b/init/security.cpp
index 3e15447..a0d63bc 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -114,10 +114,9 @@
         return {};
     }
 #elif defined(__riscv)
-    // TODO: sv48 and sv57 have both been added to the kernel, but the kernel
-    // still doesn't support more than 24 bits.
-    // https://github.com/google/android-riscv64/issues/1
-    if (SetMmapRndBitsMin(24, 24, false)) {
+    // riscv64 supports 24 rnd bits with Sv39, and starting with the 6.9 kernel,
+    // 33 bits with Sv48 and Sv57.
+    if (SetMmapRndBitsMin(33, 24, false)) {
         return {};
     }
 #elif defined(__x86_64__)
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 92e350b..de902e6 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -680,12 +680,12 @@
     }
 
     if (service_->proc_attr_.parsed_uid == std::nullopt) {
-        if (android::base::GetIntProperty("ro.vendor.api_level", 0) > __ANDROID_API_U__) {
+        if (android::base::GetIntProperty("ro.vendor.api_level", 0) > 202404) {
             return Error() << "No user specified for service '" << service_->name()
-                           << "'. Defaults to root.";
+                           << "', so it would have been root.";
         } else {
             LOG(WARNING) << "No user specified for service '" << service_->name()
-                         << "'. Defaults to root.";
+                         << "', so it is root.";
         }
     }
 
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index 2559137..b2af06c 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -24,9 +24,6 @@
     ramdisk_available: true,
     vendor_ramdisk_available: true,
     recovery_available: true,
-    vndk: {
-        enabled: true,
-    },
     host_supported: true,
     srcs: [
         "android_pubkey.cpp",
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index b7752d9..e297581 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -129,10 +129,7 @@
 cc_library {
     name: "libcutils",
     defaults: ["libcutils_defaults"],
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
     srcs: [
         "config_utils.cpp",
         "iosched_policy.cpp",
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index b9d83f2..2e4b9b4 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -68,10 +68,6 @@
     { 01771, AID_SYSTEM,       AID_MISC,         0, "data/misc" },
     { 00775, AID_MEDIA_RW,     AID_MEDIA_RW,     0, "data/media/Music" },
     { 00775, AID_MEDIA_RW,     AID_MEDIA_RW,     0, "data/media" },
-    { 00750, AID_ROOT,         AID_SHELL,        0, "data/nativetest" },
-    { 00750, AID_ROOT,         AID_SHELL,        0, "data/nativetest64" },
-    { 00750, AID_ROOT,         AID_SHELL,        0, "data/benchmarktest" },
-    { 00750, AID_ROOT,         AID_SHELL,        0, "data/benchmarktest64" },
     { 00775, AID_ROOT,         AID_ROOT,         0, "data/preloads" },
     { 00771, AID_SYSTEM,       AID_SYSTEM,       0, "data" },
     { 00755, AID_ROOT,         AID_SYSTEM,       0, "mnt" },
@@ -143,12 +139,6 @@
     { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app-private/*" },
     { 00644, AID_APP,       AID_APP,       0, "data/data/*" },
     { 00644, AID_MEDIA_RW,  AID_MEDIA_RW,  0, "data/media/*" },
-    { 00640, AID_ROOT,      AID_SHELL,     0, "data/nativetest/tests.txt" },
-    { 00640, AID_ROOT,      AID_SHELL,     0, "data/nativetest64/tests.txt" },
-    { 00750, AID_ROOT,      AID_SHELL,     0, "data/nativetest/*" },
-    { 00750, AID_ROOT,      AID_SHELL,     0, "data/nativetest64/*" },
-    { 00750, AID_ROOT,      AID_SHELL,     0, "data/benchmarktest/*" },
-    { 00750, AID_ROOT,      AID_SHELL,     0, "data/benchmarktest64/*" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "default.prop" }, // legacy
     { 00600, AID_ROOT,      AID_ROOT,      0, "system/etc/prop.default" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "odm/build.prop" }, // legacy; only for P release
diff --git a/libnetutils/Android.bp b/libnetutils/Android.bp
index 02bd2e3..0bca662 100644
--- a/libnetutils/Android.bp
+++ b/libnetutils/Android.bp
@@ -18,9 +18,6 @@
 cc_library_shared {
     name: "libnetutils",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
 
     srcs: [
         "dhcpclient.c",
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index bb855d5..d40be9f 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -72,10 +72,7 @@
     recovery_available: true,
     vendor_available: true,
     product_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
     shared_libs: [
         "libbase",
         "libcgrouprc",
diff --git a/libsysutils/Android.bp b/libsysutils/Android.bp
index 1b41a6b..842db40 100644
--- a/libsysutils/Android.bp
+++ b/libsysutils/Android.bp
@@ -5,9 +5,6 @@
 cc_library {
     name: "libsysutils",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
 
     srcs: [
         "src/SocketListener.cpp",
diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp
index 9ae73d0..f8a73ad 100644
--- a/libusbhost/Android.bp
+++ b/libusbhost/Android.bp
@@ -21,9 +21,6 @@
 cc_library {
     name: "libusbhost",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     host_supported: true,
     srcs: ["usbhost.c"],
     cflags: ["-Werror"],
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 1741187..ba19ace 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -183,10 +183,7 @@
     name: "libutils",
     defaults: ["libutils_impl_defaults"],
 
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
 
     target: {
         product: {
@@ -228,10 +225,7 @@
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
     min_sdk_version: "29",
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
 
     header_libs: [
         "libbase_headers",
diff --git a/libutils/binder/Android.bp b/libutils/binder/Android.bp
index 60b0cb6..e358391 100644
--- a/libutils/binder/Android.bp
+++ b/libutils/binder/Android.bp
@@ -22,6 +22,12 @@
         "VectorImpl.cpp",
     ],
 
+    cflags: [
+        "-Winvalid-offsetof",
+        "-Wsequence-point",
+        "-Wzero-as-null-pointer-constant",
+    ],
+
     apex_available: [
         "//apex_available:anyapex",
         "//apex_available:platform",
@@ -41,11 +47,13 @@
 cc_library {
     name: "libutils_binder",
     defaults: ["libutils_binder_impl_defaults"],
+    cmake_snapshot_supported: false,
 }
 
 cc_library_shared {
     name: "libutils_binder_sdk",
     defaults: ["libutils_binder_impl_defaults_nodeps"],
+    cmake_snapshot_supported: true,
 
     header_libs: [
         "liblog_stub",
diff --git a/libutils/binder/SharedBuffer.cpp b/libutils/binder/SharedBuffer.cpp
index 3e703db..d16bdb0 100644
--- a/libutils/binder/SharedBuffer.cpp
+++ b/libutils/binder/SharedBuffer.cpp
@@ -75,7 +75,7 @@
         LOG_ALWAYS_FATAL_IF((newSize >= (SIZE_MAX - sizeof(SharedBuffer))),
                             "Invalid buffer size %zu", newSize);
 
-        buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
+        buf = (SharedBuffer*)realloc(reinterpret_cast<void*>(buf), sizeof(SharedBuffer) + newSize);
         if (buf != nullptr) {
             buf->mSize = newSize;
             return buf;
diff --git a/libutils/binder/String16.cpp b/libutils/binder/String16.cpp
index 07a3d23..96e1477 100644
--- a/libutils/binder/String16.cpp
+++ b/libutils/binder/String16.cpp
@@ -22,6 +22,19 @@
 
 #include "SharedBuffer.h"
 
+#define LIBUTILS_PRAGMA(arg) _Pragma(#arg)
+#if defined(__clang__)
+#define LIBUTILS_PRAGMA_FOR_COMPILER(arg) LIBUTILS_PRAGMA(clang arg)
+#elif defined(__GNUC__)
+#define LIBUTILS_PRAGMA_FOR_COMPILER(arg) LIBUTILS_PRAGMA(GCC arg)
+#else
+#define LIBUTILS_PRAGMA_FOR_COMPILER(arg)
+#endif
+#define LIBUTILS_IGNORE(warning_flag)             \
+    LIBUTILS_PRAGMA_FOR_COMPILER(diagnostic push) \
+    LIBUTILS_PRAGMA_FOR_COMPILER(diagnostic ignored warning_flag)
+#define LIBUTILS_IGNORE_END() LIBUTILS_PRAGMA_FOR_COMPILER(diagnostic pop)
+
 namespace android {
 
 static const StaticString16 emptyString(u"");
@@ -347,7 +360,9 @@
 bool String16::isStaticString() const {
     // See String16.h for notes on the memory layout of String16::StaticData and
     // SharedBuffer.
+    LIBUTILS_IGNORE("-Winvalid-offsetof")
     static_assert(sizeof(SharedBuffer) - offsetof(SharedBuffer, mClientMetadata) == 4);
+    LIBUTILS_IGNORE_END()
     const uint32_t* p = reinterpret_cast<const uint32_t*>(mString);
     return (*(p - 1) & kIsSharedBufferAllocated) == 0;
 }
@@ -355,7 +370,9 @@
 size_t String16::staticStringSize() const {
     // See String16.h for notes on the memory layout of String16::StaticData and
     // SharedBuffer.
+    LIBUTILS_IGNORE("-Winvalid-offsetof")
     static_assert(sizeof(SharedBuffer) - offsetof(SharedBuffer, mClientMetadata) == 4);
+    LIBUTILS_IGNORE_END()
     const uint32_t* p = reinterpret_cast<const uint32_t*>(mString);
     return static_cast<size_t>(*(p - 1));
 }
diff --git a/libutils/binder/include/utils/RefBase.h b/libutils/binder/include/utils/RefBase.h
index f03e1be..b6a8707 100644
--- a/libutils/binder/include/utils/RefBase.h
+++ b/libutils/binder/include/utils/RefBase.h
@@ -555,7 +555,7 @@
 wp<T>::wp(T* other)
     : m_ptr(other)
 {
-    m_refs = other ? m_refs = other->createWeak(this) : nullptr;
+    m_refs = other ? other->createWeak(this) : nullptr;
 }
 
 template <typename T>
@@ -662,8 +662,7 @@
 template<typename T> template<typename U>
 wp<T>& wp<T>::operator = (const sp<U>& other)
 {
-    weakref_type* newRefs =
-        other != nullptr ? other->createWeak(this) : 0;
+    weakref_type* newRefs = other != nullptr ? other->createWeak(this) : nullptr;
     U* otherPtr(other.m_ptr);
     if (m_ptr) m_refs->decWeak(this);
     m_ptr = otherPtr;
@@ -695,8 +694,8 @@
 {
     if (m_ptr) {
         m_refs->decWeak(this);
-        m_refs = 0;
-        m_ptr = 0;
+        m_refs = nullptr;
+        m_ptr = nullptr;
     }
 }
 
diff --git a/libutils/binder/include/utils/TypeHelpers.h b/libutils/binder/include/utils/TypeHelpers.h
index 21d9b3d..007036b 100644
--- a/libutils/binder/include/utils/TypeHelpers.h
+++ b/libutils/binder/include/utils/TypeHelpers.h
@@ -200,7 +200,7 @@
 typename std::enable_if<use_trivial_move<TYPE>::value>::type
 inline
 move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
-    memmove(d, s, n*sizeof(TYPE));
+    memmove(reinterpret_cast<void*>(d), s, n * sizeof(TYPE));
 }
 
 template<typename TYPE>
@@ -227,7 +227,7 @@
 typename std::enable_if<use_trivial_move<TYPE>::value>::type
 inline
 move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
-    memmove(d, s, n*sizeof(TYPE));
+    memmove(reinterpret_cast<void*>(d), s, n * sizeof(TYPE));
 }
 
 template<typename TYPE>
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index 108c7c2..bd24f22 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -117,3 +117,7 @@
 llndk_libraries_txt {
     name: "llndk.libraries.txt",
 }
+
+sanitizer_libraries_txt {
+    name: "sanitizer.libraries.txt",
+}
\ No newline at end of file
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 2394b14..06e8730 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -211,26 +211,6 @@
 	$(hide) sed -i -e 's?%EXPORT_GLOBAL_SCUDO_ALLOCATION_RING_BUFFER_SIZE%?$(EXPORT_GLOBAL_SCUDO_ALLOCATION_RING_BUFFER_SIZE)?g' $@
 
 #######################################
-# sanitizer.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := sanitizer.libraries.txt
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(LOCAL_MODULE)
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_SANITIZER_RUNTIME_LIBRARIES := \
-    $(SANITIZER_STEMS) \
-    $(2ND_SANITIZER_STEMS)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_SANITIZER_RUNTIME_LIBRARIES), \
-		echo $(lib) >> $@;)
-
-#######################################
 # ramdisk_node_list
 include $(CLEAR_VARS)
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e8b737d..5953769 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -637,6 +637,7 @@
 
     mkdir /metadata/aconfig 0775 root system
     mkdir /metadata/aconfig/flags 0770 root system
+    mkdir /metadata/aconfig/maps 0775 root system
     mkdir /metadata/aconfig/boot 0775 root system
 
     mkdir /metadata/aconfig_test_missions 0775 root system
diff --git a/trusty/OWNERS b/trusty/OWNERS
index 4016792..46f1410 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -1,11 +1,5 @@
-armellel@google.com
-arve@android.com
-danielangell@google.com
-gmar@google.com
+# include OWNERS from the top level trusty repo
+include trusty:main:/OWNERS
+
 mikemcternan@google.com
-mmaurer@google.com
-ncbray@google.com
-swillden@google.com
-thurston@google.com
-trong@google.com
-wenhaowang@google.com
+swillden@google.com
\ No newline at end of file
diff --git a/trusty/metrics/include/trusty/metrics/tipc.h b/trusty/metrics/include/trusty/metrics/tipc.h
index e2cf57b..b4428d5 100644
--- a/trusty/metrics/include/trusty/metrics/tipc.h
+++ b/trusty/metrics/include/trusty/metrics/tipc.h
@@ -49,6 +49,7 @@
  * @METRICS_CMD_REQ_SHIFT:            number of bits used by @METRICS_CMD_RESP_BIT
  * @METRICS_CMD_REPORT_EVENT_DROP:    report gaps in the event stream
  * @METRICS_CMD_REPORT_CRASH:         report an app crash event
+ * @METRICS_CMD_REPORT_EXIT:          report an app exit
  * @METRICS_CMD_REPORT_STORAGE_ERROR: report trusty storage error
  */
 enum metrics_cmd {
@@ -57,7 +58,8 @@
 
     METRICS_CMD_REPORT_EVENT_DROP = (1 << METRICS_CMD_REQ_SHIFT),
     METRICS_CMD_REPORT_CRASH = (2 << METRICS_CMD_REQ_SHIFT),
-    METRICS_CMD_REPORT_STORAGE_ERROR = (3 << METRICS_CMD_REQ_SHIFT),
+    METRICS_CMD_REPORT_EXIT = (3 << METRICS_CMD_REQ_SHIFT),
+    METRICS_CMD_REPORT_STORAGE_ERROR = (4 << METRICS_CMD_REQ_SHIFT),
 };
 
 /**
@@ -92,9 +94,22 @@
 } __attribute__((__packed__));
 
 /**
+ * struct metrics_report_exit_req - arguments of %METRICS_CMD_REPORT_EXIT
+ *                                   requests
+ * @app_id: app_id in the form UUID in ascii format
+ *          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ * @exit_code: architecture-specific exit code
+ */
+struct metrics_report_exit_req {
+    char app_id[UUID_STR_SIZE];
+    uint32_t exit_code;
+} __attribute__((__packed__));
+
+/**
  * struct metrics_report_crash_req - arguments of %METRICS_CMD_REPORT_CRASH
  *                                   requests
- * @app_id: uuid of the app that crashed
+ * @app_id: app_id in the form UUID in ascii format
+ *          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  * @crash_reason: architecture-specific code representing the reason for the
  *                crash
  */
@@ -158,6 +173,7 @@
     struct metrics_req req;
     union {
         struct metrics_report_crash_req crash_args;
+        struct metrics_report_exit_req exit_args;
         struct metrics_report_storage_error_req storage_args;
     };
 } __attribute__((__packed__));
\ No newline at end of file