Merge "trusty: Update TIPC UAPI header"
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index a541f6e..e0c138b 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -282,7 +282,6 @@
         "libdebuggerd/test/elf_fake.cpp",
         "libdebuggerd/test/log_fake.cpp",
         "libdebuggerd/test/open_files_list_test.cpp",
-        "libdebuggerd/test/tombstone_test.cpp",
         "libdebuggerd/test/utility_test.cpp",
     ],
 
diff --git a/debuggerd/libdebuggerd/gwp_asan.cpp b/debuggerd/libdebuggerd/gwp_asan.cpp
index ed2b974..b2077ba 100644
--- a/debuggerd/libdebuggerd/gwp_asan.cpp
+++ b/debuggerd/libdebuggerd/gwp_asan.cpp
@@ -161,112 +161,3 @@
 
   set_human_readable_cause(cause, crash_address_);
 }
-
-void GwpAsanCrashData::DumpCause(log_t* log) const {
-  if (!CrashIsMine()) {
-    ALOGE("Internal Error: DumpCause() on a non-GWP-ASan crash.");
-    return;
-  }
-
-  if (error_ == gwp_asan::Error::UNKNOWN) {
-    _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: Unknown error occurred at 0x%" PRIxPTR ".\n",
-         crash_address_);
-    return;
-  }
-
-  if (!responsible_allocation_) {
-    _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s at 0x%" PRIxPTR ".\n", error_string_,
-         crash_address_);
-    return;
-  }
-
-  uintptr_t alloc_address = __gwp_asan_get_allocation_address(responsible_allocation_);
-  size_t alloc_size = __gwp_asan_get_allocation_size(responsible_allocation_);
-
-  uintptr_t diff;
-  const char* location_str;
-
-  if (crash_address_ < alloc_address) {
-    // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef.
-    location_str = "left of";
-    diff = alloc_address - crash_address_;
-  } else if (crash_address_ - alloc_address < alloc_size) {
-    // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef.
-    location_str = "into";
-    diff = crash_address_ - alloc_address;
-  } else {
-    // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef, or
-    // Invalid Free, 47 bytes right of a 41-byte allocation at 0xdeadbeef.
-    location_str = "right of";
-    diff = crash_address_ - alloc_address;
-    if (error_ == gwp_asan::Error::BUFFER_OVERFLOW) {
-      diff -= alloc_size;
-    }
-  }
-
-  // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'.
-  const char* byte_suffix = "s";
-  if (diff == 1) {
-    byte_suffix = "";
-  }
-  _LOG(log, logtype::HEADER,
-       "Cause: [GWP-ASan]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n",
-       error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address);
-}
-
-bool GwpAsanCrashData::HasDeallocationTrace() const {
-  assert(CrashIsMine() && "HasDeallocationTrace(): Crash is not mine!");
-  if (!responsible_allocation_ || !__gwp_asan_is_deallocated(responsible_allocation_)) {
-    return false;
-  }
-  return true;
-}
-
-void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const {
-  assert(HasDeallocationTrace() && "DumpDeallocationTrace(): No dealloc trace!");
-  uint64_t thread_id = __gwp_asan_get_deallocation_thread_id(responsible_allocation_);
-
-  std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]);
-  size_t num_frames =
-      __gwp_asan_get_deallocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength);
-
-  if (thread_id == gwp_asan::kInvalidThreadID) {
-    _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread <unknown>:\n");
-  } else {
-    _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %" PRIu64 ":\n", thread_id);
-  }
-
-  unwinder->SetDisplayBuildID(true);
-  for (size_t i = 0; i < num_frames; ++i) {
-    unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]);
-    frame_data.num = i;
-    _LOG(log, logtype::BACKTRACE, "    %s\n", unwinder->FormatFrame(frame_data).c_str());
-  }
-}
-
-bool GwpAsanCrashData::HasAllocationTrace() const {
-  assert(CrashIsMine() && "HasAllocationTrace(): Crash is not mine!");
-  return responsible_allocation_ != nullptr;
-}
-
-void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const {
-  assert(HasAllocationTrace() && "DumpAllocationTrace(): No dealloc trace!");
-  uint64_t thread_id = __gwp_asan_get_allocation_thread_id(responsible_allocation_);
-
-  std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]);
-  size_t num_frames =
-      __gwp_asan_get_allocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength);
-
-  if (thread_id == gwp_asan::kInvalidThreadID) {
-    _LOG(log, logtype::BACKTRACE, "\nallocated by thread <unknown>:\n");
-  } else {
-    _LOG(log, logtype::BACKTRACE, "\nallocated by thread %" PRIu64 ":\n", thread_id);
-  }
-
-  unwinder->SetDisplayBuildID(true);
-  for (size_t i = 0; i < num_frames; ++i) {
-    unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]);
-    frame_data.num = i;
-    _LOG(log, logtype::BACKTRACE, "    %s\n", unwinder->FormatFrame(frame_data).c_str());
-  }
-}
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h
index f9c2481..a979370 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h
@@ -52,26 +52,6 @@
   // allocator crash state.
   uintptr_t GetFaultAddress() const;
 
-  // Dump the GWP-ASan stringified cause of this crash. May only be called if
-  // CrashIsMine() returns true.
-  void DumpCause(log_t* log) const;
-
-  // Returns whether this crash has a deallocation trace. May only be called if
-  // CrashIsMine() returns true.
-  bool HasDeallocationTrace() const;
-
-  // Dump the GWP-ASan deallocation trace for this crash. May only be called if
-  // HasDeallocationTrace() returns true.
-  void DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const;
-
-  // Returns whether this crash has a allocation trace. May only be called if
-  // CrashIsMine() returns true.
-  bool HasAllocationTrace() const;
-
-  // Dump the GWP-ASan allocation trace for this crash. May only be called if
-  // HasAllocationTrace() returns true.
-  void DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const;
-
   void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const;
 
  protected:
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h b/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h
index c3b95d6..172ffe9 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/scudo.h
@@ -34,16 +34,12 @@
 
   bool CrashIsMine() const;
 
-  void DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const;
   void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const;
 
  private:
   scudo_error_info error_info_ = {};
   uintptr_t untagged_fault_addr_;
 
-  void DumpReport(const scudo_error_report* report, log_t* log,
-                  unwindstack::Unwinder* unwinder) const;
-
   void FillInCause(Cause* cause, const scudo_error_report* report,
                    unwindstack::Unwinder* unwinder) const;
 };
diff --git a/debuggerd/libdebuggerd/scudo.cpp b/debuggerd/libdebuggerd/scudo.cpp
index a2933f2..a4836d7 100644
--- a/debuggerd/libdebuggerd/scudo.cpp
+++ b/debuggerd/libdebuggerd/scudo.cpp
@@ -130,87 +130,3 @@
     FillInCause(tombstone->add_causes(), &error_info_.reports[report_num++], unwinder);
   }
 }
-
-void ScudoCrashData::DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const {
-  if (error_info_.reports[1].error_type != UNKNOWN) {
-    _LOG(log, logtype::HEADER,
-         "\nNote: multiple potential causes for this crash were detected, listing them in "
-         "decreasing order of likelihood.\n");
-  }
-
-  size_t report_num = 0;
-  while (report_num < sizeof(error_info_.reports) / sizeof(error_info_.reports[0]) &&
-         error_info_.reports[report_num].error_type != UNKNOWN) {
-    DumpReport(&error_info_.reports[report_num++], log, unwinder);
-  }
-}
-
-void ScudoCrashData::DumpReport(const scudo_error_report* report, log_t* log,
-                                unwindstack::Unwinder* unwinder) const {
-  const char *error_type_str;
-  switch (report->error_type) {
-    case USE_AFTER_FREE:
-      error_type_str = "Use After Free";
-      break;
-    case BUFFER_OVERFLOW:
-      error_type_str = "Buffer Overflow";
-      break;
-    case BUFFER_UNDERFLOW:
-      error_type_str = "Buffer Underflow";
-      break;
-    default:
-      error_type_str = "Unknown";
-      break;
-  }
-
-  uintptr_t diff;
-  const char* location_str;
-
-  if (untagged_fault_addr_ < report->allocation_address) {
-    // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef.
-    location_str = "left of";
-    diff = report->allocation_address - untagged_fault_addr_;
-  } else if (untagged_fault_addr_ - report->allocation_address < report->allocation_size) {
-    // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef.
-    location_str = "into";
-    diff = untagged_fault_addr_ - report->allocation_address;
-  } else {
-    // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef.
-    location_str = "right of";
-    diff = untagged_fault_addr_ - report->allocation_address - report->allocation_size;
-  }
-
-  // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'.
-  const char* byte_suffix = "s";
-  if (diff == 1) {
-    byte_suffix = "";
-  }
-  _LOG(log, logtype::HEADER,
-       "\nCause: [MTE]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n",
-       error_type_str, diff, byte_suffix, location_str, report->allocation_size,
-       report->allocation_address);
-
-  if (report->allocation_trace[0]) {
-    _LOG(log, logtype::BACKTRACE, "\nallocated by thread %u:\n", report->allocation_tid);
-    unwinder->SetDisplayBuildID(true);
-    for (size_t i = 0; i < arraysize(report->allocation_trace) && report->allocation_trace[i];
-         ++i) {
-      unwindstack::FrameData frame_data =
-          unwinder->BuildFrameFromPcOnly(report->allocation_trace[i]);
-      frame_data.num = i;
-      _LOG(log, logtype::BACKTRACE, "    %s\n", unwinder->FormatFrame(frame_data).c_str());
-    }
-  }
-
-  if (report->deallocation_trace[0]) {
-    _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %u:\n", report->deallocation_tid);
-    unwinder->SetDisplayBuildID(true);
-    for (size_t i = 0; i < arraysize(report->deallocation_trace) && report->deallocation_trace[i];
-         ++i) {
-      unwindstack::FrameData frame_data =
-          unwinder->BuildFrameFromPcOnly(report->deallocation_trace[i]);
-      frame_data.num = i;
-      _LOG(log, logtype::BACKTRACE, "    %s\n", unwinder->FormatFrame(frame_data).c_str());
-    }
-  }
-}
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
deleted file mode 100644
index 1cbfb56..0000000
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ /dev/null
@@ -1,205 +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 <stdlib.h>
-#include <sys/mman.h>
-#include <time.h>
-
-#include <memory>
-#include <string>
-
-#include <android-base/file.h>
-#include <android-base/properties.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "libdebuggerd/utility.h"
-
-#include "UnwinderMock.h"
-#include "host_signal_fixup.h"
-#include "log_fake.h"
-
-#include "gwp_asan.cpp"
-
-using ::testing::MatchesRegex;
-
-class TombstoneTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    unwinder_mock_.reset(new UnwinderMock());
-
-    char tmp_file[256];
-    const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
-    memcpy(tmp_file, data_template, sizeof(data_template));
-    int tombstone_fd = mkstemp(tmp_file);
-    if (tombstone_fd == -1) {
-      const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
-      memcpy(tmp_file, tmp_template, sizeof(tmp_template));
-      tombstone_fd = mkstemp(tmp_file);
-      if (tombstone_fd == -1) {
-        abort();
-      }
-    }
-    if (unlink(tmp_file) == -1) {
-      abort();
-    }
-
-    log_.tfd = tombstone_fd;
-    amfd_data_.clear();
-    log_.amfd_data = &amfd_data_;
-    log_.crashed_tid = 12;
-    log_.current_tid = 12;
-    log_.should_retrieve_logcat = false;
-
-    resetLogs();
-  }
-
-  virtual void TearDown() {
-    if (log_.tfd >= 0) {
-      close(log_.tfd);
-    }
-  }
-
-  std::unique_ptr<UnwinderMock> unwinder_mock_;
-
-  log_t log_;
-  std::string amfd_data_;
-};
-
-class GwpAsanCrashDataTest : public GwpAsanCrashData {
-public:
-  GwpAsanCrashDataTest(
-      gwp_asan::Error error,
-      const gwp_asan::AllocationMetadata *responsible_allocation) :
-      GwpAsanCrashData(nullptr, ProcessInfo{}, ThreadInfo{}) {
-    is_gwp_asan_responsible_ = true;
-    error_ = error;
-    responsible_allocation_ = responsible_allocation;
-    error_string_ = gwp_asan::ErrorToString(error_);
-  }
-
-  void SetCrashAddress(uintptr_t crash_address) {
-    crash_address_ = crash_address;
-  }
-};
-
-TEST_F(TombstoneTest, gwp_asan_cause_uaf_exact) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::USE_AFTER_FREE, &meta);
-  crash_data.SetCrashAddress(0x1000);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(tombstone_contents, MatchesRegex("Cause: \\[GWP-ASan\\]: Use After Free, 0 bytes "
-                                               "into a 32-byte allocation at 0x[a-fA-F0-9]+\n"));
-}
-
-TEST_F(TombstoneTest, gwp_asan_cause_double_free) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::DOUBLE_FREE, &meta);
-  crash_data.SetCrashAddress(0x1000);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(tombstone_contents, MatchesRegex("Cause: \\[GWP-ASan\\]: Double Free, 0 bytes into a "
-                                               "32-byte allocation at 0x[a-fA-F0-9]+\n"));
-}
-
-TEST_F(TombstoneTest, gwp_asan_cause_overflow) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_OVERFLOW, &meta);
-  crash_data.SetCrashAddress(0x1025);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(
-      tombstone_contents,
-      MatchesRegex(
-          "Cause: \\[GWP-ASan\\]: Buffer Overflow, 5 bytes right of a 32-byte "
-          "allocation at 0x[a-fA-F0-9]+\n"));
-}
-
-TEST_F(TombstoneTest, gwp_asan_cause_underflow) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_UNDERFLOW, &meta);
-  crash_data.SetCrashAddress(0xffe);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(
-      tombstone_contents,
-      MatchesRegex(
-          "Cause: \\[GWP-ASan\\]: Buffer Underflow, 2 bytes left of a 32-byte "
-          "allocation at 0x[a-fA-F0-9]+\n"));
-}
-
-TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_inside) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta);
-  crash_data.SetCrashAddress(0x1001);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(
-      tombstone_contents,
-      MatchesRegex(
-          "Cause: \\[GWP-ASan\\]: Invalid \\(Wild\\) Free, 1 byte into a 32-byte "
-          "allocation at 0x[a-fA-F0-9]+\n"));
-}
-
-TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_outside) {
-  gwp_asan::AllocationMetadata meta;
-  meta.Addr = 0x1000;
-  meta.RequestedSize = 32;
-
-  GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta);
-  crash_data.SetCrashAddress(0x1021);
-
-  crash_data.DumpCause(&log_);
-  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
-  std::string tombstone_contents;
-  ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
-  ASSERT_THAT(
-      tombstone_contents,
-      MatchesRegex(
-          "Cause: \\[GWP-ASan\\]: Invalid \\(Wild\\) Free, 33 bytes right of a 32-byte "
-          "allocation at 0x[a-fA-F0-9]+\n"));
-}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 960173a..6863894 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -364,8 +364,8 @@
                        const struct ext4_super_block* sb, int* fs_stat) {
     bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
     bool want_quota = entry.fs_mgr_flags.quota;
-    bool want_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);
-
+    // Enable projid support by default
+    bool want_projid = true;
     if (has_quota == want_quota) {
         return;
     }
@@ -2208,8 +2208,10 @@
     // Devices upgrading to dynamic partitions are allowed to specify a super
     // partition name. This includes cuttlefish, which is a non-A/B device.
     std::string super_partition;
-    if (fs_mgr_get_boot_config_from_bootconfig_source("super_partition", &super_partition) ||
-        fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
+    if (fs_mgr_get_boot_config("force_super_partition", &super_partition)) {
+        return super_partition;
+    }
+    if (fs_mgr_get_boot_config("super_partition", &super_partition)) {
         if (fs_mgr_get_slot_suffix().empty()) {
             return super_partition;
         }
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index bb49873..6f59ed3 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -156,11 +156,10 @@
     LERROR << __FUNCTION__ << ": Format " << entry.blk_device << " as '" << entry.fs_type << "'";
 
     bool needs_casefold = false;
-    bool needs_projid = false;
+    bool needs_projid = true;
 
     if (entry.mount_point == "/data") {
         needs_casefold = android::base::GetBoolProperty("external_storage.casefold.enabled", false);
-        needs_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);
     }
 
     if (entry.fs_type == "f2fs") {
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 996fa5e..82b5275 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -126,8 +126,12 @@
 
 bool fs_mgr_in_recovery() {
     // Check the existence of recovery binary instead of using the compile time
-    // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
-    // defined, albeit not in recovery. More details: system/core/init/README.md
+    // __ANDROID_RECOVERY__ macro.
+    // If BOARD_USES_RECOVERY_AS_BOOT is true, both normal and recovery boot
+    // mode would use the same init binary, which would mean during normal boot
+    // the '/init' binary is actually a symlink pointing to
+    // init_second_stage.recovery, which would be compiled with
+    // __ANDROID_RECOVERY__ defined.
     return fs_mgr_access("/system/bin/recovery");
 }
 
diff --git a/fs_mgr/libsnapshot/OWNERS b/fs_mgr/libsnapshot/OWNERS
index 37319fe..9d2b877 100644
--- a/fs_mgr/libsnapshot/OWNERS
+++ b/fs_mgr/libsnapshot/OWNERS
@@ -2,3 +2,4 @@
 balsini@google.com
 dvander@google.com
 elsk@google.com
+akailash@google.com
diff --git a/fs_mgr/libsnapshot/inspect_cow.cpp b/fs_mgr/libsnapshot/inspect_cow.cpp
index 548ba00..167ff8c 100644
--- a/fs_mgr/libsnapshot/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/inspect_cow.cpp
@@ -155,6 +155,7 @@
     }
     StringSink sink;
     bool success = true;
+    uint64_t xor_ops = 0, copy_ops = 0, replace_ops = 0, zero_ops = 0;
     while (!iter->Done()) {
         const CowOperation& op = iter->Get();
 
@@ -187,9 +188,26 @@
             }
         }
 
+        if (op.type == kCowCopyOp) {
+            copy_ops++;
+        } else if (op.type == kCowReplaceOp) {
+            replace_ops++;
+        } else if (op.type == kCowZeroOp) {
+            zero_ops++;
+        } else if (op.type == kCowXorOp) {
+            xor_ops++;
+        }
+
         iter->Next();
     }
 
+    if (!opt.silent) {
+        auto total_ops = replace_ops + zero_ops + copy_ops + xor_ops;
+        std::cout << "Total-data-ops: " << total_ops << "Replace-ops: " << replace_ops
+                  << " Zero-ops: " << zero_ops << " Copy-ops: " << copy_ops
+                  << " Xor_ops: " << xor_ops << std::endl;
+    }
+
     return success;
 }
 
diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
index 0b88567..c31772b 100644
--- a/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
@@ -223,8 +223,6 @@
 int main(int argc, char** argv) {
     android::base::InitLogging(argv, &android::base::KernelLogger);
 
-    LOG(INFO) << "snapuserd daemon about to start";
-
     android::snapshot::Daemon& daemon = android::snapshot::Daemon::Instance();
 
     if (!daemon.StartDaemon(argc, argv)) {
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
index 0cb41d3..c26a2cd 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
@@ -288,9 +288,6 @@
                 while (pending_ios_to_complete) {
                     struct io_uring_cqe* cqe;
 
-                    // We need to make sure to reap all the I/O's submitted
-                    // even if there are any errors observed.
-                    //
                     // io_uring_wait_cqe can potentially return -EAGAIN or -EINTR;
                     // these error codes are not truly I/O errors; we can retry them
                     // by re-populating the SQE entries and submitting the I/O
@@ -300,11 +297,13 @@
                     if (ret) {
                         SNAP_LOG(ERROR) << "Merge: io_uring_wait_cqe failed: " << ret;
                         status = false;
+                        break;
                     }
 
                     if (cqe->res < 0) {
                         SNAP_LOG(ERROR) << "Merge: io_uring_wait_cqe failed with res: " << cqe->res;
                         status = false;
+                        break;
                     }
 
                     io_uring_cqe_seen(ring_.get(), cqe);
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
index 7d9d392..fa2866f 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -395,9 +395,6 @@
     while (pending_ios_to_complete) {
         struct io_uring_cqe* cqe;
 
-        // We need to make sure to reap all the I/O's submitted
-        // even if there are any errors observed.
-        //
         // io_uring_wait_cqe can potentially return -EAGAIN or -EINTR;
         // these error codes are not truly I/O errors; we can retry them
         // by re-populating the SQE entries and submitting the I/O
@@ -407,11 +404,13 @@
         if (ret) {
             SNAP_LOG(ERROR) << "Read-ahead - io_uring_wait_cqe failed: " << ret;
             status = false;
+            break;
         }
 
         if (cqe->res < 0) {
             SNAP_LOG(ERROR) << "Read-ahead - io_uring_Wait_cqe failed with res: " << cqe->res;
             status = false;
+            break;
         }
 
         io_uring_cqe_seen(ring_.get(), cqe);
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index 7e3924a..d82d566 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -96,7 +96,7 @@
         "device-tests",
     ],
     test_options: {
-        min_shipping_api_level: 31,
+        min_shipping_api_level: 29,
     },
     require_root: true,
     auto_gen_config: true,
@@ -109,9 +109,9 @@
     ],
     shared_libs: [
         "libbase",
-        "libfs_mgr",
     ],
     static_libs: [
+        "libfs_mgr",
         "libfstab",
         "libgmock",
         "libgtest",
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index 415e67e..b5fac53 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -102,7 +102,7 @@
 }
 
 TEST(fs, NoDtFstab) {
-    if (GetVsrLevel() <= __ANDROID_API_S__) {
+    if (GetVsrLevel() < __ANDROID_API_Q__) {
         GTEST_SKIP();
     }
 
diff --git a/healthd/Android.bp b/healthd/Android.bp
index 24777c8..f180006 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -22,9 +22,15 @@
         "libutils",
         "libbase",
 
-        // Need latest HealthInfo definition from headers of this shared
-        // library. Clients don't need to link to this.
+        // Need HealthInfo definition from headers of these shared
+        // libraries. Clients don't need to link to these.
         "android.hardware.health@2.1",
+        "android.hardware.health-V1-ndk",
+    ],
+    whole_static_libs: [
+        // Need to translate HIDL to AIDL to support legacy APIs in
+        // BatteryMonitor.
+        "android.hardware.health-translate-ndk",
     ],
     header_libs: ["libhealthd_headers"],
     export_header_lib_headers: ["libhealthd_headers"],
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 5890f9a..a7571a2 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -31,10 +31,12 @@
 #include <memory>
 #include <optional>
 
+#include <aidl/android/hardware/health/HealthInfo.h>
 #include <android-base/file.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 #include <android/hardware/health/2.1/types.h>
+#include <android/hardware/health/translate-ndk.h>
 #include <batteryservice/BatteryService.h>
 #include <cutils/klog.h>
 #include <cutils/properties.h>
@@ -52,10 +54,54 @@
 using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
 using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
 using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
-using android::hardware::health::V1_0::BatteryHealth;
-using android::hardware::health::V1_0::BatteryStatus;
-using android::hardware::health::V2_1::BatteryCapacityLevel;
-using android::hardware::health::V2_1::Constants;
+using aidl::android::hardware::health::BatteryCapacityLevel;
+using aidl::android::hardware::health::BatteryHealth;
+using aidl::android::hardware::health::BatteryStatus;
+using aidl::android::hardware::health::HealthInfo;
+
+namespace {
+
+// Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls.
+// Skips storageInfo and diskStats.
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+                     ::android::hardware::health::V1_0::HealthInfo* out) {
+    out->chargerAcOnline = in.chargerAcOnline;
+    out->chargerUsbOnline = in.chargerUsbOnline;
+    out->chargerWirelessOnline = in.chargerWirelessOnline;
+    out->maxChargingCurrent = in.maxChargingCurrentMicroamps;
+    out->maxChargingVoltage = in.maxChargingVoltageMicrovolts;
+    out->batteryStatus =
+            static_cast<::android::hardware::health::V1_0::BatteryStatus>(in.batteryStatus);
+    out->batteryHealth =
+            static_cast<::android::hardware::health::V1_0::BatteryHealth>(in.batteryHealth);
+    out->batteryPresent = in.batteryPresent;
+    out->batteryLevel = in.batteryLevel;
+    out->batteryVoltage = in.batteryVoltageMillivolts;
+    out->batteryTemperature = in.batteryTemperatureTenthsCelsius;
+    out->batteryCurrent = in.batteryCurrentMicroamps;
+    out->batteryCycleCount = in.batteryCycleCount;
+    out->batteryFullCharge = in.batteryFullChargeUah;
+    out->batteryChargeCounter = in.batteryChargeCounterUah;
+    out->batteryTechnology = in.batteryTechnology;
+}
+
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+                     ::android::hardware::health::V2_0::HealthInfo* out) {
+    translateToHidl(in, &out->legacy);
+    out->batteryCurrentAverage = in.batteryCurrentAverageMicroamps;
+    // Skip storageInfo and diskStats
+}
+
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+                     ::android::hardware::health::V2_1::HealthInfo* out) {
+    translateToHidl(in, &out->legacy);
+    out->batteryCapacityLevel = static_cast<android::hardware::health::V2_1::BatteryCapacityLevel>(
+            in.batteryCapacityLevel);
+    out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds;
+    out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah;
+}
+
+}  // namespace
 
 namespace android {
 
@@ -74,17 +120,14 @@
     return std::nullopt;
 }
 
-static void initHealthInfo(HealthInfo_2_1* health_info_2_1) {
-    *health_info_2_1 = HealthInfo_2_1{};
-
-    // HIDL enum values are zero initialized, so they need to be initialized
-    // properly.
-    health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED;
-    health_info_2_1->batteryChargeTimeToFullNowSeconds =
-            (int64_t)Constants::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED;
-    auto* props = &health_info_2_1->legacy.legacy;
-    props->batteryStatus = BatteryStatus::UNKNOWN;
-    props->batteryHealth = BatteryHealth::UNKNOWN;
+static void initHealthInfo(HealthInfo* health_info) {
+    *health_info = {
+            .batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED,
+            .batteryChargeTimeToFullNowSeconds =
+                    (int64_t)HealthInfo::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED,
+            .batteryStatus = BatteryStatus::UNKNOWN,
+            .batteryHealth = BatteryHealth::UNKNOWN,
+    };
 }
 
 BatteryMonitor::BatteryMonitor()
@@ -92,22 +135,31 @@
       mBatteryDevicePresent(false),
       mBatteryFixedCapacity(0),
       mBatteryFixedTemperature(0),
-      mChargerDockOnline(false),
-      mHealthInfo(std::make_unique<HealthInfo_2_1>()) {
+      mHealthInfo(std::make_unique<HealthInfo>()) {
     initHealthInfo(mHealthInfo.get());
 }
 
 BatteryMonitor::~BatteryMonitor() {}
 
-const HealthInfo_1_0& BatteryMonitor::getHealthInfo_1_0() const {
-    return getHealthInfo_2_0().legacy;
+HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const {
+    HealthInfo_1_0 health_info_1_0;
+    translateToHidl(*mHealthInfo, &health_info_1_0);
+    return health_info_1_0;
 }
 
-const HealthInfo_2_0& BatteryMonitor::getHealthInfo_2_0() const {
-    return getHealthInfo_2_1().legacy;
+HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const {
+    HealthInfo_2_0 health_info_2_0;
+    translateToHidl(*mHealthInfo, &health_info_2_0);
+    return health_info_2_0;
 }
 
-const HealthInfo_2_1& BatteryMonitor::getHealthInfo_2_1() const {
+HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const {
+    HealthInfo_2_1 health_info_2_1;
+    translateToHidl(*mHealthInfo, &health_info_2_1);
+    return health_info_2_1;
+}
+
+const HealthInfo& BatteryMonitor::getHealthInfo() const {
     return *mHealthInfo;
 }
 
@@ -175,46 +227,48 @@
     return *ret;
 }
 
-int BatteryMonitor::readFromFile(const String8& path, std::string* buf) {
+static int readFromFile(const String8& path, std::string* buf) {
+    buf->clear();
     if (android::base::ReadFileToString(path.c_str(), buf)) {
         *buf = android::base::Trim(*buf);
     }
     return buf->length();
 }
 
-BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) {
+static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
     static SysfsStringEnumMap<int> supplyTypeMap[] = {
-            {"Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
-            {"Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY},
-            {"UPS", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"Mains", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB", ANDROID_POWER_SUPPLY_TYPE_USB},
-            {"USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_C", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC},
-            {"USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB},
-            {"Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
-            {"Dock", ANDROID_POWER_SUPPLY_TYPE_DOCK},
+            {"Unknown", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
+            {"Battery", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_BATTERY},
+            {"UPS", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"Mains", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
+            {"USB_DCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_HVDCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_CDP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_ACA", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_C", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_PD", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+            {"USB_PD_DRP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
+            {"Wireless", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
+            {"Dock", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_DOCK},
             {NULL, 0},
     };
     std::string buf;
 
-    if (readFromFile(path, &buf) <= 0)
-        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+    if (readFromFile(path, &buf) <= 0) {
+        return BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+    }
 
     auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
     if (!ret) {
         KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
-        *ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+        *ret = BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
     }
 
     return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
 }
 
-bool BatteryMonitor::getBooleanField(const String8& path) {
+static bool getBooleanField(const String8& path) {
     std::string buf;
     bool value = false;
 
@@ -225,7 +279,7 @@
     return value;
 }
 
-int BatteryMonitor::getIntField(const String8& path) {
+static int getIntField(const String8& path) {
     std::string buf;
     int value = 0;
 
@@ -235,7 +289,7 @@
     return value;
 }
 
-bool BatteryMonitor::isScopedPowerSupply(const char* name) {
+static bool isScopedPowerSupply(const char* name) {
     constexpr char kScopeDevice[] = "Device";
 
     String8 path;
@@ -247,32 +301,31 @@
 void BatteryMonitor::updateValues(void) {
     initHealthInfo(mHealthInfo.get());
 
-    HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
-
     if (!mHealthdConfig->batteryPresentPath.isEmpty())
-        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
+        mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
     else
-        props.batteryPresent = mBatteryDevicePresent;
+        mHealthInfo->batteryPresent = mBatteryDevicePresent;
 
-    props.batteryLevel = mBatteryFixedCapacity ?
-        mBatteryFixedCapacity :
-        getIntField(mHealthdConfig->batteryCapacityPath);
-    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
+    mHealthInfo->batteryLevel = mBatteryFixedCapacity
+                                        ? mBatteryFixedCapacity
+                                        : getIntField(mHealthdConfig->batteryCapacityPath);
+    mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
 
     if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
-        props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath);
+        mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
 
     if (!mHealthdConfig->batteryFullChargePath.isEmpty())
-        props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);
+        mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
 
     if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
-        props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
+        mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
 
     if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
-        props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
+        mHealthInfo->batteryChargeCounterUah =
+                getIntField(mHealthdConfig->batteryChargeCounterPath);
 
     if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())
-        mHealthInfo->legacy.batteryCurrentAverage =
+        mHealthInfo->batteryCurrentAverageMicroamps =
                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
 
     if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
@@ -283,9 +336,9 @@
         mHealthInfo->batteryFullChargeDesignCapacityUah =
                 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
 
-    props.batteryTemperature = mBatteryFixedTemperature ?
-        mBatteryFixedTemperature :
-        getIntField(mHealthdConfig->batteryTemperaturePath);
+    mHealthInfo->batteryTemperatureTenthsCelsius =
+            mBatteryFixedTemperature ? mBatteryFixedTemperature
+                                     : getIntField(mHealthdConfig->batteryTemperaturePath);
 
     std::string buf;
 
@@ -293,13 +346,13 @@
         mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
 
     if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
-        props.batteryStatus = getBatteryStatus(buf.c_str());
+        mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str());
 
     if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
-        props.batteryHealth = getBatteryHealth(buf.c_str());
+        mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str());
 
     if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
-        props.batteryTechnology = String8(buf.c_str());
+        mHealthInfo->batteryTechnology = String8(buf.c_str());
 
     double MaxPower = 0;
 
@@ -313,29 +366,26 @@
                               mChargerNames[i].string());
             switch(readPowerSupplyType(path)) {
             case ANDROID_POWER_SUPPLY_TYPE_AC:
-                props.chargerAcOnline = true;
+                mHealthInfo->chargerAcOnline = true;
                 break;
             case ANDROID_POWER_SUPPLY_TYPE_USB:
-                props.chargerUsbOnline = true;
+                mHealthInfo->chargerUsbOnline = true;
                 break;
             case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
-                props.chargerWirelessOnline = true;
+                mHealthInfo->chargerWirelessOnline = true;
                 break;
             case ANDROID_POWER_SUPPLY_TYPE_DOCK:
-                mChargerDockOnline = true;
+                mHealthInfo->chargerDockOnline = true;
                 break;
             default:
                 path.clear();
                 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
                                   mChargerNames[i].string());
-                if (access(path.string(), R_OK) == 0) {
-                    mChargerDockOnline = true;
-                    KLOG_INFO(LOG_TAG, "%s: online\n",
-                              mChargerNames[i].string());
-                } else {
+                if (access(path.string(), R_OK) == 0)
+                    mHealthInfo->chargerDockOnline = true;
+                else
                     KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
                                  mChargerNames[i].string());
-                }
             }
             path.clear();
             path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
@@ -354,38 +404,34 @@
             double power = ((double)ChargingCurrent / MILLION) *
                            ((double)ChargingVoltage / MILLION);
             if (MaxPower < power) {
-                props.maxChargingCurrent = ChargingCurrent;
-                props.maxChargingVoltage = ChargingVoltage;
+                mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent;
+                mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage;
                 MaxPower = power;
             }
         }
     }
 }
 
-void BatteryMonitor::logValues(void) {
-    logValues(*mHealthInfo, *mHealthdConfig);
-}
-
-void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
-                               const struct healthd_config& healthd_config) {
+static void doLogValues(const HealthInfo& props, const struct healthd_config& healthd_config) {
     char dmesgline[256];
     size_t len;
-    const HealthInfo_1_0& props = health_info.legacy.legacy;
     if (props.batteryPresent) {
         snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
-                 props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "",
-                 abs(props.batteryTemperature / 10), abs(props.batteryTemperature % 10),
-                 props.batteryHealth, props.batteryStatus);
+                 props.batteryLevel, props.batteryVoltageMillivolts,
+                 props.batteryTemperatureTenthsCelsius < 0 ? "-" : "",
+                 abs(props.batteryTemperatureTenthsCelsius / 10),
+                 abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth,
+                 props.batteryStatus);
 
         len = strlen(dmesgline);
         if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
-                            props.batteryCurrent);
+                            props.batteryCurrentMicroamps);
         }
 
         if (!healthd_config.batteryFullChargePath.isEmpty()) {
             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
-                            props.batteryFullCharge);
+                            props.batteryFullChargeUah);
         }
 
         if (!healthd_config.batteryCycleCountPath.isEmpty()) {
@@ -396,17 +442,28 @@
         len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
     }
 
-    snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
+    snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s",
              props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
-             props.chargerWirelessOnline ? "w" : "");
+             props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : "");
 
     KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
 }
 
+void BatteryMonitor::logValues(const HealthInfo_2_1& health_info,
+                               const struct healthd_config& healthd_config) {
+    HealthInfo aidl_health_info;
+    (void)android::h2a::translate(health_info, &aidl_health_info);
+    doLogValues(aidl_health_info, healthd_config);
+}
+
+void BatteryMonitor::logValues(void) {
+    doLogValues(*mHealthInfo, *mHealthdConfig);
+}
+
 bool BatteryMonitor::isChargerOnline() {
-    const HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
+    const HealthInfo& props = *mHealthInfo;
     return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
-           mChargerDockOnline;
+           props.chargerDockOnline;
 }
 
 int BatteryMonitor::getChargeStatus() {
@@ -489,19 +546,19 @@
 void BatteryMonitor::dumpState(int fd) {
     int v;
     char vs[128];
-    const HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
+    const HealthInfo& props = *mHealthInfo;
 
     snprintf(vs, sizeof(vs),
              "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
              props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
-             mChargerDockOnline, props.maxChargingCurrent, props.maxChargingVoltage);
+             props.chargerDockOnline, props.maxChargingCurrentMicroamps,
+             props.maxChargingVoltageMicrovolts);
     write(fd, vs, strlen(vs));
     snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
              props.batteryStatus, props.batteryHealth, props.batteryPresent);
     write(fd, vs, strlen(vs));
-    snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n",
-             props.batteryLevel, props.batteryVoltage,
-             props.batteryTemperature);
+    snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel,
+             props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
     write(fd, vs, strlen(vs));
 
     if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
@@ -523,7 +580,7 @@
     }
 
     if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
-        snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent);
+        snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
         write(fd, vs, strlen(vs));
     }
 
@@ -533,7 +590,7 @@
     }
 
     if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
-        snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge);
+        snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
         write(fd, vs, strlen(vs));
     }
 }
@@ -551,13 +608,13 @@
 
         while ((entry = readdir(dir.get()))) {
             const char* name = entry->d_name;
-            std::vector<String8>::iterator itIgnoreName;
 
             if (!strcmp(name, ".") || !strcmp(name, ".."))
                 continue;
 
-            itIgnoreName = find(hc->ignorePowerSupplyNames.begin(),
-                                hc->ignorePowerSupplyNames.end(), String8(name));
+            std::vector<String8>::iterator itIgnoreName =
+                    find(hc->ignorePowerSupplyNames.begin(), hc->ignorePowerSupplyNames.end(),
+                         String8(name));
             if (itIgnoreName != hc->ignorePowerSupplyNames.end())
                 continue;
 
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index 89c2e25..8cbf5ea 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -25,6 +25,10 @@
 
 #include <healthd/healthd.h>
 
+namespace aidl::android::hardware::health {
+class HealthInfo;
+}  // namespace aidl::android::hardware::health
+
 namespace android {
 namespace hardware {
 namespace health {
@@ -59,9 +63,10 @@
     status_t getProperty(int id, struct BatteryProperty *val);
     void dumpState(int fd);
 
-    const android::hardware::health::V1_0::HealthInfo& getHealthInfo_1_0() const;
-    const android::hardware::health::V2_0::HealthInfo& getHealthInfo_2_0() const;
-    const android::hardware::health::V2_1::HealthInfo& getHealthInfo_2_1() const;
+    android::hardware::health::V1_0::HealthInfo getHealthInfo_1_0() const;
+    android::hardware::health::V2_0::HealthInfo getHealthInfo_2_0() const;
+    android::hardware::health::V2_1::HealthInfo getHealthInfo_2_1() const;
+    const aidl::android::hardware::health::HealthInfo& getHealthInfo() const;
 
     void updateValues(void);
     void logValues(void);
@@ -76,15 +81,7 @@
     bool mBatteryDevicePresent;
     int mBatteryFixedCapacity;
     int mBatteryFixedTemperature;
-    // TODO(b/214126090): to migrate to AIDL HealthInfo
-    bool mChargerDockOnline;
-    std::unique_ptr<android::hardware::health::V2_1::HealthInfo> mHealthInfo;
-
-    int readFromFile(const String8& path, std::string* buf);
-    PowerSupplyType readPowerSupplyType(const String8& path);
-    bool getBooleanField(const String8& path);
-    int getIntField(const String8& path);
-    bool isScopedPowerSupply(const char* name);
+    std::unique_ptr<aidl::android::hardware::health::HealthInfo> mHealthInfo;
 };
 
 }; // namespace android
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 2401da3..3c7107a 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -147,6 +147,12 @@
 Ueventd will additionally log all messages sent to stderr from the external program to the serial
 console after the external program has exited.
 
+If the kernel command-line argument `firmware_class.path` is set, this path
+will be used first by the kernel to search for the firmware files. If found,
+ueventd will not be called at all. See the
+[kernel documentation](https://www.kernel.org/doc/html/v5.10/driver-api/firmware/fw_search_path.html)
+for more details on this feature.
+
 ## Coldboot
 --------
 Ueventd must create devices in `/dev` for all devices that have already sent their uevents before
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 74d8aac..0580f86 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -23,6 +23,8 @@
 #include <functional>
 #include <map>
 
+#include <android-base/logging.h>
+
 namespace android {
 namespace init {
 
@@ -42,8 +44,11 @@
     if (!events) {
         return Error() << "Must specify events";
     }
-    auto sp = std::make_shared<decltype(handler)>(std::move(handler));
-    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
+
+    Info info;
+    info.events = events;
+    info.handler = std::make_shared<decltype(handler)>(std::move(handler));
+    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(info));
     if (!inserted) {
         return Error() << "Cannot specify two epoll handlers for a given FD";
     }
@@ -84,8 +89,14 @@
     }
     std::vector<std::shared_ptr<Handler>> pending_functions;
     for (int i = 0; i < num_events; ++i) {
-        auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
-        pending_functions.emplace_back(std::move(sp));
+        auto& info = *reinterpret_cast<Info*>(ev[i].data.ptr);
+        if ((info.events & (EPOLLIN | EPOLLPRI)) == (EPOLLIN | EPOLLPRI) &&
+            (ev[i].events & EPOLLIN) != ev[i].events) {
+            // This handler wants to know about exception events, and just got one.
+            // Log something informational.
+            LOG(ERROR) << "Received unexpected epoll event set: " << ev[i].events;
+        }
+        pending_functions.emplace_back(info.handler);
     }
 
     return pending_functions;
diff --git a/init/epoll.h b/init/epoll.h
index 0df5289..f58ae8d 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -46,8 +46,13 @@
             std::optional<std::chrono::milliseconds> timeout);
 
   private:
+    struct Info {
+        std::shared_ptr<Handler> handler;
+        uint32_t events;
+    };
+
     android::base::unique_fd epoll_fd_;
-    std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
+    std::map<int, Info> epoll_handlers_;
 };
 
 }  // namespace init
diff --git a/init/init.cpp b/init/init.cpp
index 1df4c44..eca7bc5 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -33,7 +33,6 @@
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>
 
-#include <filesystem>
 #include <functional>
 #include <map>
 #include <memory>
@@ -47,7 +46,6 @@
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
-#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <backtrace/Backtrace.h>
@@ -646,7 +644,8 @@
         PLOG(FATAL) << "failed to create signalfd";
     }
 
-    if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
+    constexpr int flags = EPOLLIN | EPOLLPRI;
+    if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd, flags); !result.ok()) {
         LOG(FATAL) << result.error();
     }
 }
@@ -775,82 +774,6 @@
     return {};
 }
 
-static bool SystemReadSmokeTest() {
-    std::string dev = "/dev/block/mapper/system"s + fs_mgr_get_slot_suffix();
-    android::base::unique_fd fd(open(dev.c_str(), O_RDONLY));
-    if (fd < 0) {
-        PLOG(ERROR) << "open " << dev << " failed, will not diangose snapuserd hangs";
-        return false;
-    }
-
-    for (size_t i = 1; i <= 100; i++) {
-        // Skip around the partition a bit.
-        size_t offset = i * 4096 * 512;
-
-        char b;
-        ssize_t n = TEMP_FAILURE_RETRY(pread(fd.get(), &b, 1, offset));
-        if (n < 0) {
-            PLOG(ERROR) << "snapuserd smoke test read failed";
-            return false;
-        }
-    }
-    return true;
-}
-
-static void DiagnoseSnapuserdHang(pid_t pid) {
-    bool succeeded = false;
-
-    std::mutex m;
-    std::condition_variable cv;
-
-    // Enforce an ordering between this and the thread startup, by taking the
-    // lock before we lanuch the thread.
-    std::unique_lock<std::mutex> cv_lock(m);
-
-    std::thread t([&]() -> void {
-        std::lock_guard<std::mutex> lock(m);
-        succeeded = SystemReadSmokeTest();
-        cv.notify_all();
-    });
-
-    auto join = android::base::make_scope_guard([&]() -> void {
-        // If the smoke test is hung, then this will too. We expect the device to
-        // automatically reboot once the watchdog kicks in.
-        t.join();
-    });
-
-    auto now = std::chrono::system_clock::now();
-    auto deadline = now + 10s;
-    auto status = cv.wait_until(cv_lock, deadline);
-    if (status == std::cv_status::timeout) {
-        LOG(ERROR) << "snapuserd smoke test timed out";
-    } else if (!succeeded) {
-        LOG(ERROR) << "snapuserd smoke test failed";
-    }
-
-    if (succeeded) {
-        LOG(INFO) << "snapuserd smoke test succeeded";
-        return;
-    }
-
-    while (true) {
-        LOG(ERROR) << "snapuserd problem detected, printing open fds";
-
-        std::error_code ec;
-        std::string proc_dir = "/proc/" + std::to_string(pid) + "/fd";
-        for (const auto& entry : std::filesystem::directory_iterator(proc_dir)) {
-            std::string target;
-            if (android::base::Readlink(entry.path(), &target)) {
-                LOG(ERROR) << "snapuserd opened: " << target;
-            } else {
-                LOG(ERROR) << "snapuserd opened: " << entry.path();
-            }
-        }
-
-        std::this_thread::sleep_for(10s);
-    }
-}
-
 int SecondStageMain(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
@@ -864,11 +787,6 @@
     InitKernelLogging(argv);
     LOG(INFO) << "init second stage started!";
 
-    if (auto pid = GetSnapuserdFirstStagePid()) {
-        std::thread t(DiagnoseSnapuserdHang, *pid);
-        t.detach();
-    }
-
     // Update $PATH in the case the second stage init is newer than first stage init, where it is
     // first set.
     if (setenv("PATH", _PATH_DEFPATH, 1) != 0) {
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 57c311a..35bd415 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -202,7 +202,7 @@
     const std::string fullname = interface_name + "/" + instance_name;
 
     for (const auto& svc : *service_list_) {
-        if (svc->interfaces().count(fullname) > 0) {
+        if (svc->interfaces().count(fullname) > 0 && !service_->is_override()) {
             return Error() << "Interface '" << fullname << "' redefined in " << service_->name()
                            << " but is already defined by " << svc->name();
         }
diff --git a/init/sigchld_handler.cpp b/init/sigchld_handler.cpp
index 9b2c7d9..6fc64df 100644
--- a/init/sigchld_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -95,7 +95,10 @@
         LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
     }
 
-    if (!service) return pid;
+    if (!service) {
+        LOG(INFO) << name << " did not have an associated service entry and will not be reaped";
+        return pid;
+    }
 
     service->Reap(siginfo);
 
diff --git a/libcutils/include/cutils/multiuser.h b/libcutils/include/cutils/multiuser.h
index 9a2305c..0575ccf 100644
--- a/libcutils/include/cutils/multiuser.h
+++ b/libcutils/include/cutils/multiuser.h
@@ -30,6 +30,8 @@
 extern appid_t multiuser_get_app_id(uid_t uid);
 
 extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id);
+extern uid_t multiuser_get_sdk_sandbox_uid(userid_t user_id, appid_t app_id);
+extern uid_t multiuser_convert_sdk_sandbox_to_app_uid(uid_t uid);
 
 extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id);
 extern gid_t multiuser_get_ext_gid(userid_t user_id, appid_t app_id);
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 8e6b81c..8bb8652 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -133,6 +133,10 @@
 #define AID_THREAD_NETWORK 1084   /* Thread Network subsystem */
 #define AID_DICED 1085            /* Android's DICE daemon */
 #define AID_DMESGD 1086           /* dmesg parsing daemon for kernel report collection */
+#define AID_JC_WEAVER 1087        /* Javacard Weaver HAL - to manage omapi ARA rules */
+#define AID_JC_STRONGBOX 1088     /* Javacard Strongbox HAL - to manage omapi ARA rules */
+#define AID_JC_IDENTITYCRED 1089  /* Javacard Identity Cred HAL - to manage omapi ARA rules */
+#define AID_SDK_SANDBOX 1090      /* SDK sandbox virtual UID */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
@@ -210,6 +214,10 @@
  */
 #define AID_OVERFLOWUID 65534 /* unmapped user in the user namespace */
 
+/* use the ranges below to determine whether a process is sdk sandbox */
+#define AID_SDK_SANDBOX_PROCESS_START 20000 /* start of uids allocated to sdk sandbox processes */
+#define AID_SDK_SANDBOX_PROCESS_END 29999   /* end of uids allocated to sdk sandbox processes */
+
 /* use the ranges below to determine whether a process is isolated */
 #define AID_ISOLATED_START 90000 /* start of uids for fully isolated sandboxed processes */
 #define AID_ISOLATED_END 99999   /* end of uids for fully isolated sandboxed processes */
diff --git a/libcutils/include/private/android_projectid_config.h b/libcutils/include/private/android_projectid_config.h
index 7ef3854..56a39a6 100644
--- a/libcutils/include/private/android_projectid_config.h
+++ b/libcutils/include/private/android_projectid_config.h
@@ -49,3 +49,13 @@
 #define PROJECT_ID_EXT_OBB_START 40000
 /* End of project IDs for apps to mark external OBB data. */
 #define PROJECT_ID_EXT_OBB_END 49999
+
+/* Start of project IDs for apps to mark internal app data. */
+#define PROJECT_ID_APP_START 50000
+/* End of project IDs for apps to mark internal app data. */
+#define PROJECT_ID_APP_END 59999
+
+/* Start of project IDs for apps to mark internal app cache data. */
+#define PROJECT_ID_APP_CACHE_START 60000
+/* End of project IDs for apps to mark internal app cache data. */
+#define PROJECT_ID_APP_CACHE_END 69999
diff --git a/libcutils/multiuser.cpp b/libcutils/multiuser.cpp
index 0fd3d0c..967f991 100644
--- a/libcutils/multiuser.cpp
+++ b/libcutils/multiuser.cpp
@@ -29,6 +29,25 @@
     return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET);
 }
 
+uid_t multiuser_get_sdk_sandbox_uid(userid_t user_id, appid_t app_id) {
+    int sdk_sandbox_offset = AID_SDK_SANDBOX_PROCESS_START - AID_APP_START;
+    if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
+        return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET) + sdk_sandbox_offset;
+    } else {
+        return -1;
+    }
+}
+
+uid_t multiuser_convert_sdk_sandbox_to_app_uid(uid_t uid) {
+    appid_t app_id = multiuser_get_app_id(uid);
+    int sdk_sandbox_offset = AID_SDK_SANDBOX_PROCESS_START - AID_APP_START;
+    if (app_id >= AID_SDK_SANDBOX_PROCESS_START && app_id <= AID_SDK_SANDBOX_PROCESS_END) {
+        return uid - sdk_sandbox_offset;
+    } else {
+        return -1;
+    }
+}
+
 gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id) {
     if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
         return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_CACHE_GID_START);
diff --git a/libcutils/multiuser_test.cpp b/libcutils/multiuser_test.cpp
index 4b0fd13..b57223d 100644
--- a/libcutils/multiuser_test.cpp
+++ b/libcutils/multiuser_test.cpp
@@ -18,6 +18,7 @@
 #include <gtest/gtest.h>
 
 static constexpr auto ERR_GID = static_cast<gid_t>(-1);
+static constexpr auto ERR_UID = static_cast<uid_t>(-1);
 
 TEST(MultiuserTest, TestMerge) {
     EXPECT_EQ(0U, multiuser_get_uid(0, 0));
@@ -30,6 +31,40 @@
     EXPECT_EQ(1050000U, multiuser_get_uid(10, 50000));
 }
 
+TEST(MultiuserTest, TestSdkSandboxUid) {
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 0));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 1000));
+    EXPECT_EQ(20000U, multiuser_get_sdk_sandbox_uid(0, 10000));
+    EXPECT_EQ(25000U, multiuser_get_sdk_sandbox_uid(0, 15000));
+    EXPECT_EQ(29999U, multiuser_get_sdk_sandbox_uid(0, 19999));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 50000));
+
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 0));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 1000));
+    EXPECT_EQ(1020000U, multiuser_get_sdk_sandbox_uid(10, 10000));
+    EXPECT_EQ(1025000U, multiuser_get_sdk_sandbox_uid(10, 15000));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 20000));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 50000));
+}
+
+TEST(MultiuserTest, TestSdkSandboxUidConvertation) {
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(0));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(10000));
+    EXPECT_EQ(10000U, multiuser_convert_sdk_sandbox_to_app_uid(20000));
+    EXPECT_EQ(15000U, multiuser_convert_sdk_sandbox_to_app_uid(25000));
+    EXPECT_EQ(19999U, multiuser_convert_sdk_sandbox_to_app_uid(29999));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(50000));
+
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1000000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1001000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1010000));
+    EXPECT_EQ(1010000U, multiuser_convert_sdk_sandbox_to_app_uid(1020000));
+    EXPECT_EQ(1015000U, multiuser_convert_sdk_sandbox_to_app_uid(1025000));
+    EXPECT_EQ(1019999U, multiuser_convert_sdk_sandbox_to_app_uid(1029999));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1050000));
+}
+
 TEST(MultiuserTest, TestSplitUser) {
     EXPECT_EQ(0U, multiuser_get_user_id(0));
     EXPECT_EQ(0U, multiuser_get_user_id(1000));
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 53f6065..58af8e4 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -130,6 +130,9 @@
             enabled: true,
         },
     },
+    fuzz_config: {
+       cc: ["smoreland@google.com"],
+    },
 }
 
 cc_library {
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 0518927..99fefee 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -50,11 +50,6 @@
 // log all reference counting operations
 #define PRINT_REFS 0
 
-// Continue after logging a stack trace if ~RefBase discovers that reference
-// count has never been incremented. Normally we conspicuously crash in that
-// case.
-#define DEBUG_REFBASE_DESTRUCTION 1
-
 #if !defined(_WIN32) && !defined(__APPLE__)
 // CallStack is only supported on linux type platforms.
 #define CALLSTACK_ENABLED 1
@@ -751,17 +746,19 @@
         }
     } else if (mRefs->mStrong.load(std::memory_order_relaxed) == INITIAL_STRONG_VALUE) {
         // We never acquired a strong reference on this object.
-#if DEBUG_REFBASE_DESTRUCTION
-        // Treating this as fatal is prone to causing boot loops. For debugging, it's
-        // better to treat as non-fatal.
-        ALOGD("RefBase: Explicit destruction, weak count = %d (in %p)", mRefs->mWeak.load(), this);
+
+        // TODO: make this fatal, but too much code in Android manages RefBase with
+        // new/delete manually (or using other mechanisms such as std::make_unique).
+        // However, this is dangerous because it's also common for code to use the
+        // sp<T>(T*) constructor, assuming that if the object is around, it is already
+        // owned by an sp<>.
+        ALOGW("RefBase: Explicit destruction, weak count = %d (in %p). Use sp<> to manage this "
+              "object.",
+              mRefs->mWeak.load(), this);
 
 #if CALLSTACK_ENABLED
         CallStack::logStack(LOG_TAG);
 #endif
-#else
-        LOG_ALWAYS_FATAL("RefBase: Explicit destruction, weak count = %d", mRefs->mWeak.load());
-#endif
     }
     // For debugging purposes, clear mRefs.  Ineffective against outstanding wp's.
     const_cast<weakref_impl*&>(mRefs) = nullptr;
diff --git a/libvndksupport/TEST_MAPPING b/libvndksupport/TEST_MAPPING
new file mode 100644
index 0000000..c9b3b20
--- /dev/null
+++ b/libvndksupport/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "postsubmit": [
+    {
+      "name": "libvndksupport-tests"
+    }
+  ]
+}
diff --git a/libvndksupport/tests/Android.bp b/libvndksupport/tests/Android.bp
index ba700cb..0159395 100644
--- a/libvndksupport/tests/Android.bp
+++ b/libvndksupport/tests/Android.bp
@@ -31,4 +31,6 @@
         "libvndksupport",
         "libbase",
     ],
+
+    test_suites: ["general-tests"],
 }
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 11f414f..fe23b62 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -79,7 +79,11 @@
 
 EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS :=
 ifeq ($(CLANG_COVERAGE),true)
-  EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS := export LLVM_PROFILE_FILE /data/misc/trace/clang-%20m.profraw
+  ifeq ($(CLANG_COVERAGE_CONTINUOUS_MODE),true)
+    EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS := export LLVM_PROFILE_FILE /data/misc/trace/clang%c-%20m.profraw
+  else
+    EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS := export LLVM_PROFILE_FILE /data/misc/trace/clang-%20m.profraw
+  endif
 endif
 
 # Put it here instead of in init.rc module definition,
diff --git a/shell_and_utilities/README.md b/shell_and_utilities/README.md
index f339553..ca522b7 100644
--- a/shell_and_utilities/README.md
+++ b/shell_and_utilities/README.md
@@ -34,184 +34,71 @@
 full list for a release by running `toybox` directly.
 
 
-## Android 2.3 (Gingerbread)
+## Android 13 ("T")
 
-BSD: cat dd newfs\_msdos
-
-toolbox: chmod chown cmp date df dmesg getevent getprop hd id ifconfig
-iftop insmod ioctl ionice kill ln log ls lsmod lsof mkdir mount mv
-nandread netstat notify printenv ps reboot renice rm rmdir rmmod route
-schedtop sendevent setconsole setprop sleep smd start stop sync top
-umount uptime vmstat watchprops wipe
-
-
-## Android 4.0 (IceCreamSandwich)
-
-BSD: cat dd newfs\_msdos
-
-toolbox: chmod chown cmp date df dmesg getevent getprop hd id ifconfig
-iftop insmod ioctl ionice kill ln log ls lsmod lsof mkdir mount mv
-nandread netstat notify printenv ps reboot renice rm rmdir rmmod route
-schedtop sendevent setconsole setprop sleep smd start stop sync top
-touch umount uptime vmstat watchprops wipe
-
-
-## Android 4.1-4.3 (JellyBean)
-
-BSD: cat cp dd du grep newfs\_msdos
-
-toolbox: chcon chmod chown clear cmp date df dmesg getenforce getevent
-getprop getsebool hd id ifconfig iftop insmod ioctl ionice kill ln
-load\_policy log ls lsmod lsof md5 mkdir mount mv nandread netstat notify
-printenv ps reboot renice restorecon rm rmdir rmmod route runcon schedtop
-sendevent setconsole setenforce setprop setsebool sleep smd start stop
-sync top touch umount uptime vmstat watchprops wipe
-
-
-## Android 4.4 (KitKat)
-
-BSD: cat cp dd du grep newfs\_msdos
-
-toolbox: chcon chmod chown clear cmp date df dmesg getenforce getevent
-getprop getsebool hd id ifconfig iftop insmod ioctl ionice kill ln
-load\_policy log ls lsmod lsof md5 mkdir mkswap mount mv nandread netstat
-notify printenv ps readlink renice restorecon rm rmdir rmmod route runcon
-schedtop sendevent setconsole setenforce setprop setsebool sleep smd start
-stop swapoff swapon sync top touch umount uptime vmstat watchprops wipe
-
-
-## Android 5.0 (Lollipop)
-
-BSD: cat chown cp dd du grep kill ln mv printenv rm rmdir sleep sync
-
-toolbox: chcon chmod clear cmp date df dmesg getenforce getevent getprop
-getsebool hd id ifconfig iftop insmod ioctl ionice load\_policy log ls
-lsmod lsof md5 mkdir mknod mkswap mount nandread netstat newfs\_msdos
-nohup notify ps readlink renice restorecon rmmod route runcon schedtop
-sendevent setenforce setprop setsebool smd start stop swapoff swapon
-top touch umount uptime vmstat watchprops wipe
-
-
-## Android 6.0 (Marshmallow)
-
-BSD: dd du grep
-
-toolbox: df getevent iftop ioctl ionice log ls lsof mount nandread
-newfs\_msdos ps prlimit renice sendevent start stop top uptime watchprops
-
-toybox (0.5.2-ish): acpi basename blockdev bzcat cal cat chcon chgrp chmod chown
-chroot cksum clear comm cmp cp cpio cut date dirname dmesg dos2unix echo
-env expand expr fallocate false find free getenforce getprop groups
-head hostname hwclock id ifconfig inotifyd insmod kill load\_policy ln
-logname losetup lsmod lsusb md5sum mkdir mknod mkswap mktemp modinfo
-more mountpoint mv netstat nice nl nohup od paste patch pgrep pidof
-pkill pmap printenv printf pwd readlink realpath restorecon rm rmdir
-rmmod route runcon sed seq setenforce setprop setsid sha1sum sleep sort
-split stat strings swapoff swapon sync sysctl tac tail tar taskset tee
-time timeout touch tr true truncate umount uname uniq unix2dos usleep
-vmstat wc which whoami xargs yes
-
-
-## Android 7.0 (Nougat)
-
-BSD: dd grep
-
-toolbox: getevent iftop ioctl log nandread newfs\_msdos ps prlimit
-sendevent start stop top
-
-toybox (0.7.0-ish): acpi **base64** basename blockdev bzcat cal cat chcon chgrp chmod
-chown chroot cksum clear comm cmp cp cpio cut date **df** dirname dmesg
-dos2unix **du** echo env expand expr fallocate false find **flock** free
-getenforce getprop groups head hostname hwclock id ifconfig inotifyd
-insmod **ionice** **iorenice** kill **killall** load\_policy ln logname losetup **ls**
-lsmod **lsof** lsusb md5sum mkdir mknod mkswap mktemp modinfo more *mount*
-mountpoint mv netstat nice nl nohup od paste patch pgrep pidof pkill
-pmap printenv printf pwd readlink realpath **renice** restorecon rm rmdir
-rmmod route runcon sed seq setenforce setprop setsid sha1sum sleep sort
-split stat strings swapoff swapon sync sysctl tac tail tar taskset tee
-time timeout touch tr true truncate **tty** **ulimit** umount uname uniq unix2dos
-**uptime** usleep vmstat wc which whoami xargs **xxd** yes
-
-
-## Android 8.0 (Oreo)
-
-BSD: dd grep
+BSD: fsck\_msdos newfs\_msdos
 
 bzip2: bzcat bzip2 bunzip2
 
-toolbox: getevent newfs\_msdos
-
-toybox (0.7.3-ish): acpi base64 basename blockdev cal cat chcon chgrp chmod chown
-chroot chrt cksum clear cmp comm cp cpio cut date df **diff** dirname dmesg
-dos2unix du echo env expand expr fallocate false **file** find flock free
-getenforce getprop groups **gunzip** **gzip** head hostname hwclock id ifconfig
-inotifyd insmod ionice iorenice kill killall ln load\_policy **log** logname
-losetup ls lsmod lsof **lspci** lsusb md5sum **microcom** mkdir **mkfifo** mknod
-mkswap mktemp modinfo **modprobe** more mount mountpoint mv netstat nice
-nl nohup od paste patch pgrep pidof pkill pmap printenv printf **ps** pwd
-readlink realpath renice restorecon rm rmdir rmmod runcon sed **sendevent**
-seq setenforce setprop setsid sha1sum **sha224sum** **sha256sum** **sha384sum**
-**sha512sum** sleep sort split start stat stop strings swapoff swapon sync
-sysctl tac tail tar taskset tee time timeout **top** touch tr true truncate
-tty ulimit umount uname uniq unix2dos uptime usleep **uudecode** **uuencode**
-vmstat wc which whoami xargs xxd yes **zcat**
-
-
-## Android 9.0 (Pie)
-
-BSD: dd grep
-
-bzip2: bzcat bzip2 bunzip2
+gavinhoward/bc: bc
 
 one-true-awk: awk
 
-toolbox: getevent getprop newfs\_msdos
+toolbox: getevent getprop setprop start stop
 
-toybox (0.7.6-ish): acpi base64 basename blockdev cal cat chcon chgrp chmod chown
-chroot chrt cksum clear cmp comm cp cpio cut date df diff dirname dmesg
-dos2unix du echo env expand expr fallocate false file find flock **fmt** free
-getenforce groups gunzip gzip head hostname hwclock id ifconfig inotifyd
-insmod ionice iorenice kill killall ln load\_policy log logname losetup ls
-lsmod lsof lspci lsusb md5sum microcom mkdir mkfifo mknod mkswap mktemp
-modinfo modprobe more mount mountpoint mv netstat nice nl nohup od paste
-patch pgrep pidof pkill pmap printenv printf ps pwd readlink realpath
-renice restorecon rm rmdir rmmod runcon sed sendevent seq setenforce
-setprop setsid sha1sum sha224sum sha256sum sha384sum sha512sum sleep
-sort split start stat stop strings **stty** swapoff swapon sync sysctl tac
-tail tar taskset tee time timeout top touch tr true truncate tty ulimit
-umount uname uniq unix2dos uptime usleep uudecode uuencode vmstat wc
-which whoami xargs xxd yes zcat
+toybox (0.8.6-ish): [ acpi base64 basename blkdiscard blkid blockdev cal cat chattr chcon
+chgrp chmod chown chroot chrt cksum clear cmp comm cp cpio cut date
+dd devmem df diff dirname dmesg dos2unix du echo egrep env expand
+expr fallocate false fgrep file find flock fmt free freeramdisk fsfreeze
+fsync getconf getenforce getfattr getopt grep groups gunzip gzip head
+help hostname hwclock i2cdetect i2cdump i2cget i2cset iconv id ifconfig
+inotifyd insmod install ionice iorenice iotop kill killall ln load\_policy
+log logname losetup ls lsattr lsmod lsof lspci lsusb makedevs md5sum
+microcom mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount
+mountpoint mv nbd-client nc netcat netstat nice nl nohup nproc nsenter
+od partprobe paste patch pgrep pidof ping ping6 pivot\_root pkill pmap
+printenv printf prlimit ps pwd pwdx readelf readlink realpath renice
+restorecon rev rfkill rm rmdir rmmod rtcwake runcon sed sendevent
+seq setenforce setfattr setsid sha1sum sha224sum sha256sum sha384sum
+sha512sum sleep sort split stat strings stty swapoff swapon sync sysctl
+tac tail tar taskset tee test time timeout top touch tr traceroute
+traceroute6 true truncate tty tunctl **uclampset** ulimit umount uname
+uniq unix2dos unlink unshare uptime usleep uudecode uuencode uuidgen
+vconfig vi vmstat watch wc which whoami xargs xxd yes zcat
 
 
-## Android 10 ("Q")
+## Android 12 ("S")
 
-BSD: grep fsck\_msdos newfs\_msdos
+BSD: fsck\_msdos newfs\_msdos
 
 bzip2: bzcat bzip2 bunzip2
 
+gavinhoward/bc: bc
+
 one-true-awk: awk
 
-toolbox: getevent getprop
+toolbox: getevent getprop setprop start stop
 
-toybox (0.8.0-ish): acpi base64 basename **bc** **blkid** blockdev cal cat **chattr** chcon chgrp
-chmod chown chroot chrt cksum clear cmp comm cp cpio cut date dd df
-diff dirname dmesg dos2unix du echo **egrep** env expand expr fallocate
-false **fgrep** file find flock fmt free **freeramdisk** **fsfreeze** **getconf**
-getenforce **getfattr** grep groups gunzip gzip head **help** hostname hwclock
-**i2cdetect** **i2cdump** **i2cget** **i2cset** **iconv** id ifconfig inotifyd insmod
-**install** ionice iorenice **iotop** kill killall ln load\_policy log logname
-losetup ls **lsattr** lsmod lsof lspci lsusb **makedevs** md5sum microcom
-mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount mountpoint
-mv **nbd-client** **nc** **netcat** netstat nice nl nohup **nproc** **nsenter** od **partprobe**
-paste patch pgrep pidof **ping** **ping6** **pivot\_root** pkill pmap printenv
-printf **prlimit** ps pwd **pwdx** readlink realpath renice restorecon **rev**
-**rfkill** rm rmdir rmmod runcon sed sendevent seq setenforce **setfattr**
-setprop setsid sha1sum sha224sum sha256sum sha384sum sha512sum sleep
-sort split start stat stop strings stty swapoff swapon sync sysctl
-tac tail tar taskset tee time timeout top touch tr **traceroute** **traceroute6**
-true truncate tty **tunctl** ulimit umount uname uniq unix2dos **unlink**
-**unshare** uptime usleep uudecode uuencode **uuidgen** **vconfig** vmstat **watch**
-wc which whoami xargs xxd yes zcat
+toybox (0.8.4-ish): **[** acpi base64 basename **blkdiscard** blkid blockdev cal cat chattr chcon
+chgrp chmod chown chroot chrt cksum clear cmp comm cp cpio cut date
+dd devmem df diff dirname dmesg dos2unix du echo egrep env expand
+expr fallocate false fgrep file find flock fmt free freeramdisk fsfreeze
+fsync getconf getenforce getfattr getopt grep groups gunzip gzip head
+help hostname hwclock i2cdetect i2cdump i2cget i2cset iconv id ifconfig
+inotifyd insmod install ionice iorenice iotop kill killall ln load\_policy
+log logname losetup ls lsattr lsmod lsof lspci lsusb makedevs md5sum
+microcom mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount
+mountpoint mv nbd-client nc netcat netstat nice nl nohup nproc nsenter
+od partprobe paste patch pgrep pidof ping ping6 pivot\_root pkill pmap
+printenv printf prlimit ps pwd pwdx readelf readlink realpath renice
+restorecon rev rfkill rm rmdir rmmod **rtcwake** runcon sed sendevent
+seq setenforce setfattr setsid sha1sum sha224sum sha256sum sha384sum
+sha512sum sleep sort split stat strings stty swapoff swapon sync sysctl
+tac tail tar taskset tee **test** time timeout top touch tr traceroute
+traceroute6 true truncate tty tunctl ulimit umount uname uniq unix2dos
+unlink unshare uptime usleep uudecode uuencode uuidgen vconfig vi
+vmstat watch wc which whoami xargs xxd yes zcat
+
 
 ## Android 11 ("R")
 
@@ -245,34 +132,182 @@
 usleep uudecode uuencode uuidgen vconfig **vi** vmstat watch wc which
 whoami xargs xxd yes zcat
 
-## Android ("S")
 
-BSD: fsck\_msdos newfs\_msdos
+## Android 10 ("Q")
+
+BSD: grep fsck\_msdos newfs\_msdos
 
 bzip2: bzcat bzip2 bunzip2
 
-gavinhoward/bc: bc
+one-true-awk: awk
+
+toolbox: getevent getprop
+
+toybox (0.8.0-ish): acpi base64 basename **bc** **blkid** blockdev cal cat **chattr** chcon chgrp
+chmod chown chroot chrt cksum clear cmp comm cp cpio cut date dd df
+diff dirname dmesg dos2unix du echo **egrep** env expand expr fallocate
+false **fgrep** file find flock fmt free **freeramdisk** **fsfreeze** **getconf**
+getenforce **getfattr** grep groups gunzip gzip head **help** hostname hwclock
+**i2cdetect** **i2cdump** **i2cget** **i2cset** **iconv** id ifconfig inotifyd insmod
+**install** ionice iorenice **iotop** kill killall ln load\_policy log logname
+losetup ls **lsattr** lsmod lsof lspci lsusb **makedevs** md5sum microcom
+mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount mountpoint
+mv **nbd-client** **nc** **netcat** netstat nice nl nohup **nproc** **nsenter** od **partprobe**
+paste patch pgrep pidof **ping** **ping6** **pivot\_root** pkill pmap printenv
+printf **prlimit** ps pwd **pwdx** readlink realpath renice restorecon **rev**
+**rfkill** rm rmdir rmmod runcon sed sendevent seq setenforce **setfattr**
+setprop setsid sha1sum sha224sum sha256sum sha384sum sha512sum sleep
+sort split start stat stop strings stty swapoff swapon sync sysctl
+tac tail tar taskset tee time timeout top touch tr **traceroute** **traceroute6**
+true truncate tty **tunctl** ulimit umount uname uniq unix2dos **unlink**
+**unshare** uptime usleep uudecode uuencode **uuidgen** **vconfig** vmstat **watch**
+wc which whoami xargs xxd yes zcat
+
+
+## Android 9.0 (Pie)
+
+BSD: dd grep
+
+bzip2: bzcat bzip2 bunzip2
 
 one-true-awk: awk
 
-toolbox: getevent getprop setprop start stop
+toolbox: getevent getprop newfs\_msdos
 
-toybox (0.8.4-ish): **[** acpi base64 basename **blkdiscard** blkid blockdev cal cat chattr chcon
-chgrp chmod chown chroot chrt cksum clear cmp comm cp cpio cut date
-dd devmem df diff dirname dmesg dos2unix du echo egrep env expand
-expr fallocate false fgrep file find flock fmt free freeramdisk fsfreeze
-fsync getconf getenforce getfattr getopt grep groups gunzip gzip head
-help hostname hwclock i2cdetect i2cdump i2cget i2cset iconv id ifconfig
-inotifyd insmod install ionice iorenice iotop kill killall ln load\_policy
-log logname losetup ls lsattr lsmod lsof lspci lsusb makedevs md5sum
-microcom mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount
-mountpoint mv nbd-client nc netcat netstat nice nl nohup nproc nsenter
-od partprobe paste patch pgrep pidof ping ping6 pivot\_root pkill pmap
-printenv printf prlimit ps pwd pwdx readelf readlink realpath renice
-restorecon rev rfkill rm rmdir rmmod **rtcwake** runcon sed sendevent
-seq setenforce setfattr setsid sha1sum sha224sum sha256sum sha384sum
-sha512sum sleep sort split stat strings stty swapoff swapon sync sysctl
-tac tail tar taskset tee **test** time timeout top touch tr traceroute
-traceroute6 true truncate tty tunctl ulimit umount uname uniq unix2dos
-unlink unshare uptime usleep uudecode uuencode uuidgen vconfig vi
-vmstat watch wc which whoami xargs xxd yes zcat
+toybox (0.7.6-ish): acpi base64 basename blockdev cal cat chcon chgrp chmod chown
+chroot chrt cksum clear cmp comm cp cpio cut date df diff dirname dmesg
+dos2unix du echo env expand expr fallocate false file find flock **fmt** free
+getenforce groups gunzip gzip head hostname hwclock id ifconfig inotifyd
+insmod ionice iorenice kill killall ln load\_policy log logname losetup ls
+lsmod lsof lspci lsusb md5sum microcom mkdir mkfifo mknod mkswap mktemp
+modinfo modprobe more mount mountpoint mv netstat nice nl nohup od paste
+patch pgrep pidof pkill pmap printenv printf ps pwd readlink realpath
+renice restorecon rm rmdir rmmod runcon sed sendevent seq setenforce
+setprop setsid sha1sum sha224sum sha256sum sha384sum sha512sum sleep
+sort split start stat stop strings **stty** swapoff swapon sync sysctl tac
+tail tar taskset tee time timeout top touch tr true truncate tty ulimit
+umount uname uniq unix2dos uptime usleep uudecode uuencode vmstat wc
+which whoami xargs xxd yes zcat
+
+
+## Android 8.0 (Oreo)
+
+BSD: dd grep
+
+bzip2: bzcat bzip2 bunzip2
+
+toolbox: getevent newfs\_msdos
+
+toybox (0.7.3-ish): acpi base64 basename blockdev cal cat chcon chgrp chmod chown
+chroot chrt cksum clear cmp comm cp cpio cut date df **diff** dirname dmesg
+dos2unix du echo env expand expr fallocate false **file** find flock free
+getenforce getprop groups **gunzip** **gzip** head hostname hwclock id ifconfig
+inotifyd insmod ionice iorenice kill killall ln load\_policy **log** logname
+losetup ls lsmod lsof **lspci** lsusb md5sum **microcom** mkdir **mkfifo** mknod
+mkswap mktemp modinfo **modprobe** more mount mountpoint mv netstat nice
+nl nohup od paste patch pgrep pidof pkill pmap printenv printf **ps** pwd
+readlink realpath renice restorecon rm rmdir rmmod runcon sed **sendevent**
+seq setenforce setprop setsid sha1sum **sha224sum** **sha256sum** **sha384sum**
+**sha512sum** sleep sort split start stat stop strings swapoff swapon sync
+sysctl tac tail tar taskset tee time timeout **top** touch tr true truncate
+tty ulimit umount uname uniq unix2dos uptime usleep **uudecode** **uuencode**
+vmstat wc which whoami xargs xxd yes **zcat**
+
+
+## Android 7.0 (Nougat)
+
+BSD: dd grep
+
+toolbox: getevent iftop ioctl log nandread newfs\_msdos ps prlimit
+sendevent start stop top
+
+toybox (0.7.0-ish): acpi **base64** basename blockdev bzcat cal cat chcon chgrp chmod
+chown chroot cksum clear comm cmp cp cpio cut date **df** dirname dmesg
+dos2unix **du** echo env expand expr fallocate false find **flock** free
+getenforce getprop groups head hostname hwclock id ifconfig inotifyd
+insmod **ionice** **iorenice** kill **killall** load\_policy ln logname losetup **ls**
+lsmod **lsof** lsusb md5sum mkdir mknod mkswap mktemp modinfo more *mount*
+mountpoint mv netstat nice nl nohup od paste patch pgrep pidof pkill
+pmap printenv printf pwd readlink realpath **renice** restorecon rm rmdir
+rmmod route runcon sed seq setenforce setprop setsid sha1sum sleep sort
+split stat strings swapoff swapon sync sysctl tac tail tar taskset tee
+time timeout touch tr true truncate **tty** **ulimit** umount uname uniq unix2dos
+**uptime** usleep vmstat wc which whoami xargs **xxd** yes
+
+
+## Android 6.0 (Marshmallow)
+
+BSD: dd du grep
+
+toolbox: df getevent iftop ioctl ionice log ls lsof mount nandread
+newfs\_msdos ps prlimit renice sendevent start stop top uptime watchprops
+
+toybox (0.5.2-ish): acpi basename blockdev bzcat cal cat chcon chgrp chmod chown
+chroot cksum clear comm cmp cp cpio cut date dirname dmesg dos2unix echo
+env expand expr fallocate false find free getenforce getprop groups
+head hostname hwclock id ifconfig inotifyd insmod kill load\_policy ln
+logname losetup lsmod lsusb md5sum mkdir mknod mkswap mktemp modinfo
+more mountpoint mv netstat nice nl nohup od paste patch pgrep pidof
+pkill pmap printenv printf pwd readlink realpath restorecon rm rmdir
+rmmod route runcon sed seq setenforce setprop setsid sha1sum sleep sort
+split stat strings swapoff swapon sync sysctl tac tail tar taskset tee
+time timeout touch tr true truncate umount uname uniq unix2dos usleep
+vmstat wc which whoami xargs yes
+
+
+## Android 5.0 (Lollipop)
+
+BSD: cat chown cp dd du grep kill ln mv printenv rm rmdir sleep sync
+
+toolbox: chcon chmod clear cmp date df dmesg getenforce getevent getprop
+getsebool hd id ifconfig iftop insmod ioctl ionice load\_policy log ls
+lsmod lsof md5 mkdir mknod mkswap mount nandread netstat newfs\_msdos
+nohup notify ps readlink renice restorecon rmmod route runcon schedtop
+sendevent setenforce setprop setsebool smd start stop swapoff swapon
+top touch umount uptime vmstat watchprops wipe
+
+
+## Android 4.4 (KitKat)
+
+BSD: cat cp dd du grep newfs\_msdos
+
+toolbox: chcon chmod chown clear cmp date df dmesg getenforce getevent
+getprop getsebool hd id ifconfig iftop insmod ioctl ionice kill ln
+load\_policy log ls lsmod lsof md5 mkdir mkswap mount mv nandread netstat
+notify printenv ps readlink renice restorecon rm rmdir rmmod route runcon
+schedtop sendevent setconsole setenforce setprop setsebool sleep smd start
+stop swapoff swapon sync top touch umount uptime vmstat watchprops wipe
+
+
+## Android 4.1-4.3 (JellyBean)
+
+BSD: cat cp dd du grep newfs\_msdos
+
+toolbox: chcon chmod chown clear cmp date df dmesg getenforce getevent
+getprop getsebool hd id ifconfig iftop insmod ioctl ionice kill ln
+load\_policy log ls lsmod lsof md5 mkdir mount mv nandread netstat notify
+printenv ps reboot renice restorecon rm rmdir rmmod route runcon schedtop
+sendevent setconsole setenforce setprop setsebool sleep smd start stop
+sync top touch umount uptime vmstat watchprops wipe
+
+
+## Android 4.0 (IceCreamSandwich)
+
+BSD: cat dd newfs\_msdos
+
+toolbox: chmod chown cmp date df dmesg getevent getprop hd id ifconfig
+iftop insmod ioctl ionice kill ln log ls lsmod lsof mkdir mount mv
+nandread netstat notify printenv ps reboot renice rm rmdir rmmod route
+schedtop sendevent setconsole setprop sleep smd start stop sync top
+touch umount uptime vmstat watchprops wipe
+
+
+## Android 2.3 (Gingerbread)
+
+BSD: cat dd newfs\_msdos
+
+toolbox: chmod chown cmp date df dmesg getevent getprop hd id ifconfig
+iftop insmod ioctl ionice kill ln log ls lsmod lsof mkdir mount mv
+nandread netstat notify printenv ps reboot renice rm rmdir rmmod route
+schedtop sendevent setconsole setprop sleep smd start stop sync top
+umount uptime vmstat watchprops wipe