Merge "TEST_MAPPING: enable KernelLibcutilsTest in kernel-presubmit"
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index baa5bfb..c6a535a 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -566,20 +566,23 @@
     process_info = g_callbacks.get_process_info();
   }
 
-  // GWP-ASan catches use-after-free and heap-buffer-overflow by using PROT_NONE
-  // guard pages, which lead to SEGV. Normally, debuggerd prints a bug report
-  // and the process terminates, but in some cases, we actually want to print
-  // the bug report and let the signal handler return, and restart the process.
-  // In order to do that, we need to disable GWP-ASan's guard pages. The
-  // following callbacks handle this case.
-  gwp_asan_callbacks_t gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
-  if (signal_number == SIGSEGV && signal_has_si_addr(info) &&
-      gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery &&
-      gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report &&
-      gwp_asan_callbacks.debuggerd_gwp_asan_post_crash_report &&
-      gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery(info->si_addr)) {
-    gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report(info->si_addr);
-    process_info.recoverable_gwp_asan_crash = true;
+  gwp_asan_callbacks_t gwp_asan_callbacks = {};
+  if (g_callbacks.get_gwp_asan_callbacks != nullptr) {
+    // GWP-ASan catches use-after-free and heap-buffer-overflow by using PROT_NONE
+    // guard pages, which lead to SEGV. Normally, debuggerd prints a bug report
+    // and the process terminates, but in some cases, we actually want to print
+    // the bug report and let the signal handler return, and restart the process.
+    // In order to do that, we need to disable GWP-ASan's guard pages. The
+    // following callbacks handle this case.
+    gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
+    if (signal_number == SIGSEGV && signal_has_si_addr(info) &&
+        gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery &&
+        gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report &&
+        gwp_asan_callbacks.debuggerd_gwp_asan_post_crash_report &&
+        gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery(info->si_addr)) {
+      gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report(info->si_addr);
+      process_info.recoverable_gwp_asan_crash = true;
+    }
   }
 
   // If sival_int is ~0, it means that the fallback handler has been called
@@ -764,6 +767,7 @@
 bool debuggerd_handle_signal(int signal_number, siginfo_t* info, void* context) {
   if (signal_number != SIGSEGV || !signal_has_si_addr(info)) return false;
 
+  if (g_callbacks.get_gwp_asan_callbacks == nullptr) return false;
   gwp_asan_callbacks_t gwp_asan_callbacks = g_callbacks.get_gwp_asan_callbacks();
   if (gwp_asan_callbacks.debuggerd_needs_gwp_asan_recovery == nullptr ||
       gwp_asan_callbacks.debuggerd_gwp_asan_pre_crash_report == nullptr ||
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index f5fd3a1..bec4ef1 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -775,7 +775,7 @@
 
 #endif
 
-static unique_fd unzip_to_file(ZipArchiveHandle zip, const char* entry_name) {
+static unique_fd UnzipToFile(ZipArchiveHandle zip, const char* entry_name) {
     unique_fd fd(make_temporary_fd(entry_name));
 
     ZipEntry64 zip_entry;
@@ -1646,14 +1646,22 @@
     return task;
 }
 
-void AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>* tasks) {
+bool AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>* tasks) {
     // expands "resize-partitions" into individual commands : resize {os_partition_1}, resize
     // {os_partition_2}, etc.
     std::vector<std::unique_ptr<Task>> resize_tasks;
     std::optional<size_t> loc;
+    std::vector<char> contents;
+    if (!fp->source->ReadFile("super_empty.img", &contents)) {
+        return false;
+    }
+    auto metadata = android::fs_mgr::ReadFromImageBlob(contents.data(), contents.size());
+    if (!metadata) {
+        return false;
+    }
     for (size_t i = 0; i < tasks->size(); i++) {
         if (auto flash_task = tasks->at(i)->AsFlashTask()) {
-            if (should_flash_in_userspace(flash_task->GetPartitionAndSlot())) {
+            if (should_flash_in_userspace(*metadata.get(), flash_task->GetPartitionAndSlot())) {
                 if (!loc) {
                     loc = i;
                 }
@@ -1665,11 +1673,11 @@
     // if no logical partitions (although should never happen since system will always need to be
     // flashed)
     if (!loc) {
-        return;
+        return false;
     }
     tasks->insert(tasks->begin() + loc.value(), std::make_move_iterator(resize_tasks.begin()),
                   std::make_move_iterator(resize_tasks.end()));
-    return;
+    return true;
 }
 
 static bool IsIgnore(const std::vector<std::string>& command) {
@@ -1750,7 +1758,9 @@
         }
         tasks.insert(it, std::move(flash_super_task));
     } else {
-        AddResizeTasks(fp, &tasks);
+        if (!AddResizeTasks(fp, &tasks)) {
+            LOG(WARNING) << "Failed to add resize tasks";
+        };
     }
     return tasks;
 }
@@ -1774,28 +1784,8 @@
 
     CancelSnapshotIfNeeded();
 
-    std::vector<char> contents;
-    if (!fp_->source->ReadFile("fastboot-info.txt", &contents)) {
-        LOG(VERBOSE) << "Flashing from hardcoded images. fastboot-info.txt is empty or does not "
-                        "exist";
-        HardcodedFlash();
-        return;
-    }
-
-    std::vector<std::unique_ptr<Task>> tasks =
-            ParseFastbootInfo(fp_, Split({contents.data(), contents.size()}, "\n"));
-
-    if (tasks.empty()) {
-        LOG(FATAL) << "Invalid fastboot-info.txt file.";
-    }
-    LOG(VERBOSE) << "Flashing from fastboot-info.txt";
-    for (auto& task : tasks) {
-        task->Run();
-    }
-    if (fp_->wants_wipe) {
-        // avoid adding duplicate wipe tasks in fastboot main code.
-        fp_->wants_wipe = false;
-    }
+    HardcodedFlash();
+    return;
 }
 
 void FlashAllTool::CheckRequirements() {
@@ -1928,7 +1918,7 @@
 }
 
 unique_fd ZipImageSource::OpenFile(const std::string& name) const {
-    return unzip_to_file(zip_, name.c_str());
+    return UnzipToFile(zip_, name.c_str());
 }
 
 static void do_update(const char* filename, FlashingPlan* fp) {
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 0a1f1eb..abdf636 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -144,7 +144,7 @@
                                            const std::vector<std::string>& parts);
 std::unique_ptr<Task> ParseFastbootInfoLine(const FlashingPlan* fp,
                                             const std::vector<std::string>& command);
-void AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks);
+bool AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks);
 std::vector<std::unique_ptr<Task>> ParseFastbootInfo(const FlashingPlan* fp,
                                                      const std::vector<std::string>& file);
 
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index cb12060..9ce2cfd 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -214,11 +214,9 @@
 
     for (const auto& task : tasks) {
         if (auto flash_task = task->AsFlashTask()) {
-            if (should_flash_in_userspace(flash_task->GetPartitionAndSlot())) {
-                auto partition = flash_task->GetPartitionAndSlot();
-                if (!helper->AddPartition(partition, flash_task->GetImageName(), false)) {
-                    return nullptr;
-                }
+            auto partition = flash_task->GetPartitionAndSlot();
+            if (!helper->AddPartition(partition, flash_task->GetImageName(), false)) {
+                return nullptr;
             }
         }
     }
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index f68d65a..bd7955a 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -244,6 +244,8 @@
         value = BatteryHealth::UNSPECIFIED_FAILURE;
     else if (status == BatteryMonitor::BH_NOT_AVAILABLE)
         value = BatteryHealth::NOT_AVAILABLE;
+    else if (status == BatteryMonitor::BH_INCONSISTENT)
+        value = BatteryHealth::INCONSISTENT;
     else
         value = BatteryHealth::UNKNOWN;
 
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index a4c013b..e9998ba 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -63,6 +63,7 @@
         BH_NEEDS_REPLACEMENT,
         BH_FAILED,
         BH_NOT_AVAILABLE,
+        BH_INCONSISTENT,
     };
 
     BatteryMonitor();
diff --git a/libutils/RefBase_test.cpp b/libutils/RefBase_test.cpp
index aed3b9b..d675598 100644
--- a/libutils/RefBase_test.cpp
+++ b/libutils/RefBase_test.cpp
@@ -28,7 +28,7 @@
 
 using namespace android;
 
-static constexpr int NITERS = 1000000;
+static constexpr int NITERS = 500000;
 
 static constexpr int INITIAL_STRONG_VALUE = 1 << 28;  // Mirroring RefBase definition.
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d755b50..0ee85c7 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -295,7 +295,7 @@
     write /proc/sys/kernel/randomize_va_space 2
     write /proc/sys/vm/mmap_min_addr 32768
     write /proc/sys/net/ipv4/ping_group_range "0 2147483647"
-    write /proc/sys/net/unix/max_dgram_qlen 600
+    write /proc/sys/net/unix/max_dgram_qlen 2400
 
     # Assign reasonable ceiling values for socket rcv/snd buffers.
     # These should almost always be overridden by the target per the
@@ -1004,6 +1004,11 @@
     exec_start derive_classpath
     load_exports /data/system/environ/classpath
 
+    # Start ART's oneshot boot service to propagate boot experiment flags to
+    # dalvik.vm.*. This needs to be done before odsign since odrefresh uses and
+    # validates those properties against the signed cache-info.xml.
+    exec_start art_boot
+
     # Start the on-device signing daemon, and wait for it to finish, to ensure
     # ART artifacts are generated if needed.
     # Must start after 'derive_classpath' to have *CLASSPATH variables set.
diff --git a/toolbox/modprobe.cpp b/toolbox/modprobe.cpp
index 17f8156..17d4e31 100644
--- a/toolbox/modprobe.cpp
+++ b/toolbox/modprobe.cpp
@@ -85,6 +85,26 @@
     }
 }
 
+// Find directories in format of "/lib/modules/x.y.z-*".
+static int KernelVersionNameFilter(const dirent* de) {
+    unsigned int major, minor;
+    static std::string kernel_version;
+    utsname uts;
+
+    if (kernel_version.empty()) {
+        if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
+            LOG(ERROR) << "Could not parse the kernel version from uname";
+            return 0;
+        }
+        kernel_version = android::base::StringPrintf("%u.%u", major, minor);
+    }
+
+    if (android::base::StartsWith(de->d_name, kernel_version)) {
+        return 1;
+    }
+    return 0;
+}
+
 }  // anonymous namespace
 
 extern "C" int modprobe_main(int argc, char** argv) {
@@ -192,9 +212,22 @@
     }
 
     if (mod_dirs.empty()) {
-        utsname uts;
-        uname(&uts);
-        mod_dirs.emplace_back(android::base::StringPrintf("/lib/modules/%s", uts.release));
+        static constexpr auto LIB_MODULES_PREFIX = "/lib/modules/";
+        dirent** kernel_dirs = NULL;
+
+        int n = scandir(LIB_MODULES_PREFIX, &kernel_dirs, KernelVersionNameFilter, NULL);
+        if (n == -1) {
+            PLOG(ERROR) << "Failed to scan dir " << LIB_MODULES_PREFIX;
+            return EXIT_FAILURE;
+        } else if (n > 0) {
+            while (n--) {
+                mod_dirs.emplace_back(LIB_MODULES_PREFIX + std::string(kernel_dirs[n]->d_name));
+            }
+        }
+        free(kernel_dirs);
+
+        // Allow modules to be directly inside /lib/modules
+        mod_dirs.emplace_back(LIB_MODULES_PREFIX);
     }
 
     LOG(DEBUG) << "mode is " << mode;
@@ -212,11 +245,6 @@
             return EXIT_FAILURE;
         }
     }
-    if (mod_dirs.empty()) {
-        LOG(ERROR) << "No module configuration directories given.";
-        print_usage();
-        return EXIT_FAILURE;
-    }
     if (parameter_count && modules.size() > 1) {
         LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
         print_usage();