Merge "bootstat: Add NTC PMIC shutdown reason." into main
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/open_files_list.h b/debuggerd/libdebuggerd/include/libdebuggerd/open_files_list.h
index d47f2dd..12a425e 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/open_files_list.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/open_files_list.h
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 
 #include <map>
+#include <memory>
 #include <optional>
 #include <string>
 #include <utility>
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index 79f3939..9eabbd3 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -33,6 +33,7 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <algorithm>
 #include <chrono>
 #include <cstdlib>
 #include <fstream>
diff --git a/fastboot/fuzzy_fastboot/test_utils.cpp b/fastboot/fuzzy_fastboot/test_utils.cpp
index 9ad98be..b80db23 100644
--- a/fastboot/fuzzy_fastboot/test_utils.cpp
+++ b/fastboot/fuzzy_fastboot/test_utils.cpp
@@ -28,6 +28,8 @@
 #include "test_utils.h"
 #include <fcntl.h>
 #include <termios.h>
+#include <algorithm>
+#include <iterator>
 #include <sstream>
 
 namespace fastboot {
diff --git a/fastboot/fuzzy_fastboot/transport_sniffer.cpp b/fastboot/fuzzy_fastboot/transport_sniffer.cpp
index 0aef350..fffa9a2 100644
--- a/fastboot/fuzzy_fastboot/transport_sniffer.cpp
+++ b/fastboot/fuzzy_fastboot/transport_sniffer.cpp
@@ -3,6 +3,7 @@
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <algorithm>
 #include <iomanip>
 #include <sstream>
 
diff --git a/fs_mgr/liblp/fuzzer/liblp_builder_fuzzer.cpp b/fs_mgr/liblp/fuzzer/liblp_builder_fuzzer.cpp
index 162c9fc..2e59332 100644
--- a/fs_mgr/liblp/fuzzer/liblp_builder_fuzzer.cpp
+++ b/fs_mgr/liblp/fuzzer/liblp_builder_fuzzer.cpp
@@ -15,6 +15,7 @@
  *
  */
 
+#include <functional>
 #include <fuzzer/FuzzedDataProvider.h>
 #include <liblp/builder.h>
 #include <liblp/property_fetcher.h>
diff --git a/fs_mgr/liblp/fuzzer/liblp_super_layout_builder_fuzzer.cpp b/fs_mgr/liblp/fuzzer/liblp_super_layout_builder_fuzzer.cpp
index a6642d7..a93e68e 100644
--- a/fs_mgr/liblp/fuzzer/liblp_super_layout_builder_fuzzer.cpp
+++ b/fs_mgr/liblp/fuzzer/liblp_super_layout_builder_fuzzer.cpp
@@ -17,6 +17,7 @@
 
 #include <android-base/unique_fd.h>
 #include <fcntl.h>
+#include <functional>
 #include <fuzzer/FuzzedDataProvider.h>
 #include <liblp/metadata_format.h>
 #include <liblp/super_layout_builder.h>
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index b5b976a..af1991a 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -308,17 +308,15 @@
         "vts",
         "general-tests",
     ],
-    compile_multilib: "both",
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
+    compile_multilib: "first",
     test_options: {
         min_shipping_api_level: 30,
+        test_runner_options: [
+            {
+                name: "force-no-test-error",
+                value: "false",
+            },
+        ],
     },
 }
 
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
index 6516499..127735d 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_reader.cpp
@@ -17,6 +17,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <algorithm>
 #include <optional>
 #include <unordered_map>
 #include <unordered_set>
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/create_cow.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/create_cow.cpp
index fd4e7da..4f8bfd2 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/create_cow.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/create_cow.cpp
@@ -36,6 +36,10 @@
 
 DEFINE_string(source, "", "Source partition image");
 DEFINE_string(target, "", "Target partition image");
+DEFINE_string(
+        output_dir, "",
+        "Output directory to write the patch file to. Defaults to current working directory if "
+        "not set.");
 DEFINE_string(compression, "lz4",
               "Compression algorithm. Default is set to lz4. Available options: lz4, zstd, gz");
 DEFINE_bool(merkel_tree, false, "If true, source image hash is obtained from verity merkel tree");
@@ -569,12 +573,15 @@
 
     source.img -> Source partition image
     target.img -> Target partition image
-    compressoin -> compression algorithm. Default set to lz4. Supported types are gz, lz4, zstd.
+    compression -> compression algorithm. Default set to lz4. Supported types are gz, lz4, zstd.
+    merkel_tree -> If true, source image hash is obtained from verity merkel tree.
+    output_dir -> Output directory to write the patch file to. Defaults to current working directory if not set.
 
 EXAMPLES
 
    $ create_snapshot $SOURCE_BUILD/system.img $TARGET_BUILD/system.img
    $ create_snapshot $SOURCE_BUILD/product.img $TARGET_BUILD/product.img --compression="zstd"
+   $ create_snapshot $SOURCE_BUILD/product.img $TARGET_BUILD/product.img --merkel_tree --output_dir=/tmp/create_snapshot_output
 
 )";
 
@@ -591,6 +598,9 @@
     std::string fname = android::base::Basename(FLAGS_target.c_str());
     auto parts = android::base::Split(fname, ".");
     std::string snapshotfile = parts[0] + ".patch";
+    if (!FLAGS_output_dir.empty()) {
+        snapshotfile = FLAGS_output_dir + "/" + snapshotfile;
+    }
     android::snapshot::CreateSnapshot snapshot(FLAGS_source, FLAGS_target, snapshotfile,
                                                FLAGS_compression, FLAGS_merkel_tree);
 
diff --git a/fs_mgr/libsnapshot/scripts/apply-update.sh b/fs_mgr/libsnapshot/scripts/apply-update.sh
index 0b10721..2a5a8a2 100755
--- a/fs_mgr/libsnapshot/scripts/apply-update.sh
+++ b/fs_mgr/libsnapshot/scripts/apply-update.sh
@@ -52,13 +52,16 @@
 # Function to flash static partitions
 flash_static_partitions() {
   local wipe_flag="$1"
+  local flash_bootloader="$2"
 
-  fastboot flash bootloader "$OUT"/bootloader.img
-  fastboot reboot bootloader
-  sleep 1
-  fastboot flash radio "$OUT"/radio.img
-  fastboot reboot bootloader
-  sleep 1
+  if (( flash_bootloader )); then
+    fastboot flash bootloader "$OUT"/bootloader.img
+    fastboot reboot bootloader
+    sleep 1
+    fastboot flash radio "$OUT"/radio.img
+    fastboot reboot bootloader
+    sleep 1
+  fi
   fastboot flashall --exclude-dynamic-partitions --disable-super-optimization --skip-reboot
 
   if (( wipe_flag )); then
@@ -120,6 +123,7 @@
 }
 
 skip_static_partitions=0
+flash_bootloader=1
 wipe_flag=0
 help_flag=0
 
@@ -132,6 +136,9 @@
     --wipe)
       wipe_flag=1
       ;;
+    --skip_bootloader)
+      flash_bootloader=0
+      ;;
     --help)
       help_flag=1
       ;;
@@ -214,7 +221,7 @@
     log_message "Rebooting device to bootloader"
     adb reboot bootloader
     log_message "Waiting to enter fastboot bootloader"
-    flash_static_partitions "$wipe_flag"
+    flash_static_partitions "$wipe_flag" "$flash_bootloader"
 fi
 
 log_message "Update completed"
diff --git a/fs_mgr/libsnapshot/snapuserd/testing/dm_user_harness.h b/fs_mgr/libsnapshot/snapuserd/testing/dm_user_harness.h
index cf26bed..507e8f3 100644
--- a/fs_mgr/libsnapshot/snapuserd/testing/dm_user_harness.h
+++ b/fs_mgr/libsnapshot/snapuserd/testing/dm_user_harness.h
@@ -19,13 +19,13 @@
 #include "harness.h"
 #include "temp_device.h"
 
+#include <snapuserd/dm_user_block_server.h>
+
 namespace android {
 namespace snapshot {
 
 using android::base::unique_fd;
 
-class DmUserBlockServerFactory;
-
 class DmUserDevice final : public IUserDevice {
   public:
     explicit DmUserDevice(std::unique_ptr<Tempdevice>&& dev);
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.h
index ecf5d5c..c6301d4 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.h
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/handler_manager.h
@@ -15,6 +15,7 @@
 #pragma once
 
 #include <memory>
+#include <mutex>
 #include <queue>
 #include <string>
 #include <thread>
diff --git a/init/capabilities.h b/init/capabilities.h
index fc80c98..b71d2cb 100644
--- a/init/capabilities.h
+++ b/init/capabilities.h
@@ -18,6 +18,7 @@
 #include <sys/capability.h>
 
 #include <bitset>
+#include <memory>
 #include <string>
 #include <type_traits>
 
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 31af94e..83e9a0d 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -103,8 +103,6 @@
 namespace android {
 namespace init {
 
-class PersistWriteThread;
-
 constexpr auto FINGERPRINT_PROP = "ro.build.fingerprint";
 constexpr auto LEGACY_FINGERPRINT_PROP = "ro.build.legacy.fingerprint";
 constexpr auto ID_PROP = "ro.build.id";
@@ -122,8 +120,6 @@
 static std::thread property_service_thread;
 static std::thread property_service_for_system_thread;
 
-static std::unique_ptr<PersistWriteThread> persist_write_thread;
-
 static PropertyInfoAreaFile property_info_area;
 
 struct PropertyAuditData {
@@ -384,6 +380,8 @@
     std::deque<std::tuple<std::string, std::string, SocketConnection>> work_;
 };
 
+static std::unique_ptr<PersistWriteThread> persist_write_thread;
+
 static std::optional<uint32_t> PropertySet(const std::string& name, const std::string& value,
                                            SocketConnection* socket, std::string* error) {
     size_t valuelen = value.size();
diff --git a/init/ueventd_test.cpp b/init/ueventd_test.cpp
index 1ac6d8e..5921ece 100644
--- a/init/ueventd_test.cpp
+++ b/init/ueventd_test.cpp
@@ -19,6 +19,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <algorithm>
 #include <atomic>
 #include <chrono>
 #include <string>
diff --git a/libcutils/android_get_control_file_test.cpp b/libcutils/android_get_control_file_test.cpp
index 8de8530..e57af5e 100644
--- a/libcutils/android_get_control_file_test.cpp
+++ b/libcutils/android_get_control_file_test.cpp
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <time.h>
 
+#include <algorithm>
 #include <string>
 
 #include <android-base/file.h>
diff --git a/libcutils/ashmem_base_test.cpp b/libcutils/ashmem_base_test.cpp
index c9b14e5..d60a973 100644
--- a/libcutils/ashmem_base_test.cpp
+++ b/libcutils/ashmem_base_test.cpp
@@ -16,6 +16,8 @@
 
 #include <gtest/gtest.h>
 
+#include <algorithm>
+
 #include <unistd.h>
 
 #include <android-base/mapped_file.h>
diff --git a/libcutils/ashmem_test.cpp b/libcutils/ashmem_test.cpp
index ccbb8c9..b0a552f 100644
--- a/libcutils/ashmem_test.cpp
+++ b/libcutils/ashmem_test.cpp
@@ -69,6 +69,15 @@
     }
 }
 
+static void waitForChildProcessExit(pid_t pid) {
+    int exitStatus;
+    pid_t childPid = waitpid(pid, &exitStatus, 0);
+
+    ASSERT_GT(childPid, 0);
+    ASSERT_TRUE(WIFEXITED(exitStatus));
+    ASSERT_EQ(0, WEXITSTATUS(exitStatus));
+}
+
 TEST(AshmemTest, ForkTest) {
     const size_t size = getpagesize();
     std::vector<uint8_t> data(size);
@@ -84,23 +93,30 @@
     ASSERT_EQ(0, memcmp(region1, data.data(), size));
     EXPECT_EQ(0, munmap(region1, size));
 
-    ASSERT_EXIT(
-        {
-            if (!ashmem_valid(fd)) {
-                _exit(3);
-            }
-            void* region2 = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-            if (region2 == MAP_FAILED) {
-                _exit(1);
-            }
-            if (memcmp(region2, data.data(), size) != 0) {
-                _exit(2);
-            }
-            memset(region2, 0, size);
-            munmap(region2, size);
-            _exit(0);
-        },
-        ::testing::ExitedWithCode(0), "");
+
+    pid_t pid = fork();
+    if (!pid) {
+        if (!ashmem_valid(fd)) {
+            _exit(3);
+        }
+
+        void *region2 = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        if (region2 == MAP_FAILED) {
+            _exit(1);
+        } else if (memcmp(region2, data.data(), size) != 0){
+            _exit(2);
+        }
+
+        // Clear the ashmem buffer here to ensure that updates to the contents
+        // of the buffer are visible across processes with a reference to the
+        // buffer.
+        memset(region2, 0, size);
+        munmap(region2, size);
+        _exit(0);
+    } else {
+        ASSERT_GT(pid, 0);
+        ASSERT_NO_FATAL_FAILURE(waitForChildProcessExit(pid));
+    }
 
     memset(data.data(), 0, size);
     void *region2;
@@ -176,26 +192,22 @@
     const size_t size = getpagesize();
     void *region;
 
-    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ));
+    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_EXEC));
     TestProtDenied(fd, size, PROT_WRITE);
-    TestProtIs(fd, PROT_READ);
+    TestProtIs(fd, PROT_READ | PROT_EXEC);
     ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ, &region));
     EXPECT_EQ(0, munmap(region, size));
 
-    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_WRITE));
-    TestProtDenied(fd, size, PROT_READ);
-    TestProtIs(fd, PROT_WRITE);
-    ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_WRITE, &region));
-    EXPECT_EQ(0, munmap(region, size));
-
-    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
-    TestProtIs(fd, PROT_READ | PROT_WRITE);
-    ASSERT_EQ(0, ashmem_set_prot_region(fd, PROT_READ));
+    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE |
+                                             PROT_EXEC));
+    TestProtIs(fd, PROT_READ | PROT_WRITE | PROT_EXEC);
+    ASSERT_EQ(0, ashmem_set_prot_region(fd, PROT_READ | PROT_EXEC));
     errno = 0;
-    ASSERT_EQ(-1, ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE))
+    ASSERT_EQ(-1, ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE |
+                                         PROT_EXEC))
         << "kernel shouldn't allow adding protection bits";
     EXPECT_EQ(EINVAL, errno);
-    TestProtIs(fd, PROT_READ);
+    TestProtIs(fd, PROT_READ | PROT_EXEC);
     TestProtDenied(fd, size, PROT_WRITE);
 }
 
@@ -203,22 +215,25 @@
     unique_fd fd;
     const size_t size = getpagesize();
 
-    int protFlags[] = { PROT_READ, PROT_WRITE };
-    for (size_t i = 0; i < arraysize(protFlags); i++) {
-        ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
-        ASSERT_EXIT(
-            {
-                if (!ashmem_valid(fd)) {
-                    _exit(3);
-                } else if (ashmem_set_prot_region(fd, protFlags[i]) >= 0) {
-                    _exit(0);
-                } else {
-                    _exit(1);
-                }
-            },
-            ::testing::ExitedWithCode(0), "");
-        ASSERT_NO_FATAL_FAILURE(TestProtDenied(fd, size, protFlags[1-i]));
+    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
+
+    pid_t pid = fork();
+    if (!pid) {
+        // Change buffer mapping permissions to read-only to ensure that
+        // updates to the buffer's mapping permissions are visible across
+        // processes that reference the buffer.
+        if (!ashmem_valid(fd)) {
+            _exit(3);
+        } else if (ashmem_set_prot_region(fd, PROT_READ) == -1) {
+            _exit(1);
+        }
+        _exit(0);
+    } else {
+        ASSERT_GT(pid, 0);
+        ASSERT_NO_FATAL_FAILURE(waitForChildProcessExit(pid));
     }
+
+    ASSERT_NO_FATAL_FAILURE(TestProtDenied(fd, size, PROT_WRITE));
 }
 
 TEST(AshmemTest, ForkMultiRegionTest) {
@@ -237,7 +252,10 @@
         EXPECT_EQ(0, munmap(region, size));
     }
 
-    ASSERT_EXIT({
+    pid_t pid = fork();
+    if (!pid) {
+        // Clear each ashmem buffer in the context of the child process to
+        // ensure that the updates are visible to the parent process later.
         for (int i = 0; i < nRegions; i++) {
             if (!ashmem_valid(fd[i])) {
                 _exit(3);
@@ -254,7 +272,10 @@
             munmap(region, size);
         }
         _exit(0);
-    }, ::testing::ExitedWithCode(0), "");
+    } else {
+        ASSERT_GT(pid, 0);
+        ASSERT_NO_FATAL_FAILURE(waitForChildProcessExit(pid));
+    }
 
     memset(data.data(), 0, size);
     for (int i = 0; i < nRegions; i++) {
diff --git a/libmodprobe/include/modprobe/modprobe.h b/libmodprobe/include/modprobe/modprobe.h
index 7b691b1..d33e17d 100644
--- a/libmodprobe/include/modprobe/modprobe.h
+++ b/libmodprobe/include/modprobe/modprobe.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <functional>
 #include <mutex>
 #include <set>
 #include <string>
diff --git a/libstats/bootstrap/BootstrapClientInternal.h b/libstats/bootstrap/BootstrapClientInternal.h
index 96238da..7879d01 100644
--- a/libstats/bootstrap/BootstrapClientInternal.h
+++ b/libstats/bootstrap/BootstrapClientInternal.h
@@ -18,6 +18,8 @@
 
 #include <android/os/IStatsBootstrapAtomService.h>
 
+#include <mutex>
+
 namespace android {
 namespace os {
 namespace stats {
diff --git a/toolbox/getprop.cpp b/toolbox/getprop.cpp
index ca345cb..7c3d94c 100644
--- a/toolbox/getprop.cpp
+++ b/toolbox/getprop.cpp
@@ -17,6 +17,7 @@
 #include <getopt.h>
 #include <sys/system_properties.h>
 
+#include <algorithm>
 #include <iostream>
 #include <string>
 #include <vector>
diff --git a/trusty/storage/proxy/watchdog.cpp b/trusty/storage/proxy/watchdog.cpp
index 6c09e26..f042fdc 100644
--- a/trusty/storage/proxy/watchdog.cpp
+++ b/trusty/storage/proxy/watchdog.cpp
@@ -18,6 +18,7 @@
 
 #include <chrono>
 #include <cstdint>
+#include <mutex>
 #include <optional>
 #include <thread>
 #include <vector>