Merge changes from topic "revert-3081452-revert-3062926-CJGHTRPCBP-GUVWVZQSHP" into main

* changes:
  Reland "[Berberis][CrashReporting] Dump guest thread inf..."
  Reland "[Berberis][CrashReporting] Extend ThreadInfo to ..."
diff --git a/init/property_service.cpp b/init/property_service.cpp
index d3cdd43..cd5933d 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -974,6 +974,17 @@
     std::string build_fingerprint = GetProperty("ro.product.brand", UNKNOWN);
     build_fingerprint += '/';
     build_fingerprint += GetProperty("ro.product.name", UNKNOWN);
+
+    // should be set in /product/etc/build.prop
+    // when we have a dev option device, and we've switched the kernel to 16kb mode
+    // we use the same system image, but we've switched out the kernel, so make it
+    // visible at a high level
+    bool has16KbDevOption =
+            android::base::GetBoolProperty("ro.product.build.16k_page.enabled", false);
+    if (has16KbDevOption && getpagesize() == 16384) {
+        build_fingerprint += "_16kb";
+    }
+
     build_fingerprint += '/';
     build_fingerprint += GetProperty("ro.product.device", UNKNOWN);
     build_fingerprint += ':';
diff --git a/init/test_upgrade_mte/AndroidTest.xml b/init/test_upgrade_mte/AndroidTest.xml
index b89cde8..e08afc0 100644
--- a/init/test_upgrade_mte/AndroidTest.xml
+++ b/init/test_upgrade_mte/AndroidTest.xml
@@ -20,11 +20,13 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
       <option name="cleanup" value="true" />
       <option name="remount-system" value="true" />
-      <option name="push" value="mte_upgrade_test.rc->/system/etc/init/mte_upgrade_test.rc" />
-      <option name="push" value="mte_upgrade_test_helper->/system/bin/mte_upgrade_test_helper" />
-      <option name="push" value="mte_upgrade_test_helper->/data/local/tmp/app_process64" />
+
+      <option name="push-file" key="mte_upgrade_test.rc" value="/system/etc/init/mte_upgrade_test.rc" />
+      <option name="push-file" key="mte_upgrade_test_helper" value="/system/bin/mte_upgrade_test_helper" />
+      <option name="push-file" key="mte_upgrade_test_helper" value="/data/local/tmp/app_process64" />
+      <option name="post-push" value="chmod 644 /system/etc/init/mte_upgrade_test.rc" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.HostTest" >
         <option name="jar" value="mte_upgrade_test.jar" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/init/test_upgrade_mte/OWNERS b/init/test_upgrade_mte/OWNERS
new file mode 100644
index 0000000..79625df
--- /dev/null
+++ b/init/test_upgrade_mte/OWNERS
@@ -0,0 +1,5 @@
+fmayer@google.com
+
+eugenis@google.com
+mitchp@google.com
+pcc@google.com
diff --git a/init/test_upgrade_mte/mte_upgrade_test_helper.cpp b/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
index 6728cc6..c4b175a 100644
--- a/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
+++ b/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
@@ -22,6 +22,7 @@
 #include <sys/prctl.h>
 #include <time.h>
 #include <unistd.h>
+
 #include <memory>
 
 int MaybeDowngrade() {
@@ -65,7 +66,5 @@
     // This binary gets run by src/com/android/tests/init/MteUpgradeTest.java, which
     // asserts that it crashes as expected.
     f[17] = 'x';
-    char buf[1];
-    read(1, buf, 1);
     return 0;
 }
diff --git a/libstats/socket_lazy/Android.bp b/libstats/socket_lazy/Android.bp
index b2cd7b2..241e87a 100644
--- a/libstats/socket_lazy/Android.bp
+++ b/libstats/socket_lazy/Android.bp
@@ -7,6 +7,12 @@
 
 cc_library_static {
     name: "libstatssocket_lazy",
+    local_include_dirs: [
+        "include",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
     header_libs: [
         "libstatssocket_headers",
     ],
@@ -28,7 +34,10 @@
         "-Wall",
         "-Werror",
     ],
-    test_suites: ["device-tests", "mts-statsd"],
+    test_suites: [
+        "device-tests",
+        "mts-statsd",
+    ],
     test_config: "libstatssocket_lazy_test.xml",
     // TODO(b/153588990): Remove when the build system properly separates.
     // 32bit and 64bit architectures.
diff --git a/libstats/socket_lazy/include/statssocket_lazy.h b/libstats/socket_lazy/include/statssocket_lazy.h
new file mode 100644
index 0000000..7dda0ba
--- /dev/null
+++ b/libstats/socket_lazy/include/statssocket_lazy.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#pragma once
+
+namespace android::statssocket::lazy {
+
+// See if libstatssocket.so is available. Early processes relying on _lazy might not have access
+// to libstatssocket.so when they start before the StatsD APEX is available.
+bool IsAvailable();
+
+}  // namespace android::statssocket::lazy
diff --git a/libstats/socket_lazy/libstatssocket_lazy.cpp b/libstats/socket_lazy/libstatssocket_lazy.cpp
index fe94ef2..d907c7e 100644
--- a/libstats/socket_lazy/libstatssocket_lazy.cpp
+++ b/libstats/socket_lazy/libstatssocket_lazy.cpp
@@ -23,8 +23,10 @@
 
 #include "log/log.h"
 
-#include "stats_event.h"
-#include "stats_socket.h"
+#include <stats_event.h>
+#include <stats_socket.h>
+
+#include "statssocket_lazy.h"
 
 // This file provides a lazy interface to libstatssocket.so to address early boot dependencies.
 // Specifically bootanimation, surfaceflinger, and lmkd run before the statsd APEX is loaded and
@@ -77,6 +79,13 @@
     return dlopen("libstatssocket.so", dlopen_flags);
 }
 
+namespace android::statssocket::lazy {
+bool IsAvailable() {
+    static const void* handle = LoadLibstatssocket(RTLD_NOW);
+    return handle != nullptr;
+}
+}  // namespace android::statssocket::lazy
+
 //
 // Initialization and symbol binding.
 
diff --git a/libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp b/libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp
index 3de6cd7..733f1e4 100644
--- a/libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp
+++ b/libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp
@@ -21,6 +21,8 @@
 #include "stats_event.h"
 #include "stats_socket.h"
 
+#include "statssocket_lazy.h"
+
 // The tests here are just for the case when libstatssocket.so cannot be loaded by
 // libstatssocket_lazy.
 class LibstatssocketLazyTest : public ::testing::Test {
@@ -57,3 +59,7 @@
 TEST_F(LibstatssocketLazyTest, NoLibstatssocketForStatsSocket) {
     EXPECT_DEATH(AStatsSocket_close(), kLoadFailed);
 }
+
+TEST_F(LibstatssocketLazyTest, IsAvailableFalse) {
+    EXPECT_FALSE(android::statssocket::lazy::IsAvailable());
+}
diff --git a/libutils/binder/String16_test.cpp b/libutils/binder/String16_test.cpp
index 6f4642e..83cc599 100644
--- a/libutils/binder/String16_test.cpp
+++ b/libutils/binder/String16_test.cpp
@@ -16,6 +16,8 @@
 
 #include <utils/String16.h>
 #include <utils/String8.h>
+#include <compare>
+#include <utility>
 
 #include <gtest/gtest.h>
 
@@ -257,3 +259,45 @@
     EXPECT_EQ(NO_MEMORY, s.insert(3, u"", SIZE_MAX));
     EXPECT_STR16EQ(u"foo!bar", s.c_str());
 }
+
+TEST(String16Test, comparisons) {
+    const char16_t* cstr1 = u"abc";
+    const char16_t* cstr2 = u"def";
+
+    // str1 and str1b will point to different blocks of memory but with equal contents.
+    String16 str1(cstr1);
+    String16 str1b(cstr1);
+    String16 str2(cstr2);
+
+    EXPECT_TRUE((str1 <=> str1b) == 0);
+    EXPECT_FALSE(str1 != str1b);
+    EXPECT_FALSE(str1 < str1b);
+    EXPECT_TRUE(str1 <= str1b);
+    EXPECT_TRUE(str1 == str1b);
+    EXPECT_TRUE(str1 >= str1b);
+    EXPECT_FALSE(str1 > str1b);
+
+    EXPECT_TRUE((str1 <=> str2) < 0);
+    EXPECT_TRUE((str2 <=> str1) > 0);
+    EXPECT_TRUE(str1 != str2);
+    EXPECT_TRUE(str1 < str2);
+    EXPECT_TRUE(str1 <= str2);
+    EXPECT_FALSE(str1 == str2);
+    EXPECT_FALSE(str1 >= str2);
+    EXPECT_FALSE(str1 > str2);
+
+    // Verify that pre-C++20 comparison operators work with a std::pair of a String8, which only
+    // provides <=> in C++20 and up. See b/339775405.
+
+    std::pair<String16, int> pair1(str1, 13);
+    std::pair<String16, int> pair1b(str1b, 13);
+    std::pair<String16, int> pair2(str2, 13);
+
+    EXPECT_TRUE(pair1 == pair1b);
+    EXPECT_FALSE(pair1 < pair1b);
+    EXPECT_FALSE(pair1 > pair1b);
+
+    EXPECT_TRUE(pair1 != pair2);
+    EXPECT_TRUE(pair1 < pair2);
+    EXPECT_FALSE(pair1 > pair2);
+}
diff --git a/libutils/binder/String8_test.cpp b/libutils/binder/String8_test.cpp
index 6f7882a..fc3c329 100644
--- a/libutils/binder/String8_test.cpp
+++ b/libutils/binder/String8_test.cpp
@@ -17,8 +17,10 @@
 #define LOG_TAG "String8_test"
 
 #include <log/log.h>
-#include <utils/String8.h>
 #include <utils/String16.h>
+#include <utils/String8.h>
+#include <compare>
+#include <utility>
 
 #include <gtest/gtest.h>
 
@@ -132,3 +134,45 @@
     EXPECT_TRUE(s.removeAll("o"));
     EXPECT_STREQ("Hell, wrld!", s.c_str());
 }
+
+TEST_F(String8Test, comparisons) {
+    const char* cstr1 = "abc";
+    const char* cstr2 = "def";
+
+    // str1 and str1b will point to different blocks of memory but with equal contents.
+    String8 str1(cstr1);
+    String8 str1b(cstr1);
+    String8 str2(cstr2);
+
+    EXPECT_TRUE((str1 <=> str1b) == 0);
+    EXPECT_FALSE(str1 != str1b);
+    EXPECT_FALSE(str1 < str1b);
+    EXPECT_TRUE(str1 <= str1b);
+    EXPECT_TRUE(str1 == str1b);
+    EXPECT_TRUE(str1 >= str1b);
+    EXPECT_FALSE(str1 > str1b);
+
+    EXPECT_TRUE((str1 <=> str2) < 0);
+    EXPECT_TRUE((str2 <=> str1) > 0);
+    EXPECT_TRUE(str1 != str2);
+    EXPECT_TRUE(str1 < str2);
+    EXPECT_TRUE(str1 <= str2);
+    EXPECT_FALSE(str1 == str2);
+    EXPECT_FALSE(str1 >= str2);
+    EXPECT_FALSE(str1 > str2);
+
+    // Verify that pre-C++20 comparison operators work with a std::pair of a String8, which only
+    // provides <=> in C++20 and up. See b/339775405.
+
+    std::pair<String8, int> pair1(str1, 13);
+    std::pair<String8, int> pair1b(str1b, 13);
+    std::pair<String8, int> pair2(str2, 13);
+
+    EXPECT_TRUE(pair1 == pair1b);
+    EXPECT_FALSE(pair1 < pair1b);
+    EXPECT_FALSE(pair1 > pair1b);
+
+    EXPECT_TRUE(pair1 != pair2);
+    EXPECT_TRUE(pair1 < pair2);
+    EXPECT_FALSE(pair1 > pair2);
+}
diff --git a/libutils/binder/include/utils/String16.h b/libutils/binder/include/utils/String16.h
index c713576..867dbac 100644
--- a/libutils/binder/include/utils/String16.h
+++ b/libutils/binder/include/utils/String16.h
@@ -29,6 +29,10 @@
 #define HAS_STRING_VIEW
 #endif
 
+#if __cplusplus >= 202002L
+#include <compare>
+#endif
+
 // ---------------------------------------------------------------------------
 
 namespace android {
@@ -105,6 +109,9 @@
     inline  bool                operator!=(const String16& other) const;
     inline  bool                operator>=(const String16& other) const;
     inline  bool                operator>(const String16& other) const;
+#if __cplusplus >= 202002L
+    inline std::strong_ordering operator<=>(const String16& other) const;
+#endif
 
     inline  bool                operator<(const char16_t* other) const;
     inline  bool                operator<=(const char16_t* other) const;
@@ -112,6 +119,9 @@
     inline  bool                operator!=(const char16_t* other) const;
     inline  bool                operator>=(const char16_t* other) const;
     inline  bool                operator>(const char16_t* other) const;
+#if __cplusplus >= 202002L
+    inline std::strong_ordering operator<=>(const char16_t* other) const;
+#endif
 
     inline                      operator const char16_t*() const;
 
@@ -334,6 +344,19 @@
     return strzcmp16(mString, size(), other.mString, other.size()) > 0;
 }
 
+#if __cplusplus >= 202002L
+inline std::strong_ordering String16::operator<=>(const String16& other) const {
+    int result = strzcmp16(mString, size(), other.mString, other.size());
+    if (result == 0) {
+        return std::strong_ordering::equal;
+    } else if (result < 0) {
+        return std::strong_ordering::less;
+    } else {
+        return std::strong_ordering::greater;
+    }
+}
+#endif
+
 inline bool String16::operator<(const char16_t* other) const
 {
     return strcmp16(mString, other) < 0;
@@ -364,6 +387,19 @@
     return strcmp16(mString, other) > 0;
 }
 
+#if __cplusplus >= 202002L
+inline std::strong_ordering String16::operator<=>(const char16_t* other) const {
+    int result = strcmp16(mString, other);
+    if (result == 0) {
+        return std::strong_ordering::equal;
+    } else if (result < 0) {
+        return std::strong_ordering::less;
+    } else {
+        return std::strong_ordering::greater;
+    }
+}
+#endif
+
 inline String16::operator const char16_t*() const
 {
     return mString;
diff --git a/libutils/binder/include/utils/String8.h b/libutils/binder/include/utils/String8.h
index 6d25072..e0d7588 100644
--- a/libutils/binder/include/utils/String8.h
+++ b/libutils/binder/include/utils/String8.h
@@ -36,6 +36,10 @@
 #define HAS_STRING_VIEW
 #endif
 
+#if __cplusplus >= 202002L
+#include <compare>
+#endif
+
 // ---------------------------------------------------------------------------
 
 namespace android {
@@ -106,6 +110,9 @@
     inline  bool                operator!=(const String8& other) const;
     inline  bool                operator>=(const String8& other) const;
     inline  bool                operator>(const String8& other) const;
+#if __cplusplus >= 202002L
+    inline std::strong_ordering operator<=>(const String8& other) const;
+#endif
 
     inline  bool                operator<(const char* other) const;
     inline  bool                operator<=(const char* other) const;
@@ -113,6 +120,9 @@
     inline  bool                operator!=(const char* other) const;
     inline  bool                operator>=(const char* other) const;
     inline  bool                operator>(const char* other) const;
+#if __cplusplus >= 202002L
+    inline std::strong_ordering operator<=>(const char* other) const;
+#endif
 
     inline                      operator const char*() const;
 
@@ -302,6 +312,19 @@
     return strcmp(mString, other.mString) > 0;
 }
 
+#if __cplusplus >= 202002L
+inline std::strong_ordering String8::operator<=>(const String8& other) const {
+    int result = strcmp(mString, other.mString);
+    if (result == 0) {
+        return std::strong_ordering::equal;
+    } else if (result < 0) {
+        return std::strong_ordering::less;
+    } else {
+        return std::strong_ordering::greater;
+    }
+}
+#endif
+
 inline bool String8::operator<(const char* other) const
 {
     return strcmp(mString, other) < 0;
@@ -332,6 +355,19 @@
     return strcmp(mString, other) > 0;
 }
 
+#if __cplusplus >= 202002L
+inline std::strong_ordering String8::operator<=>(const char* other) const {
+    int result = strcmp(mString, other);
+    if (result == 0) {
+        return std::strong_ordering::equal;
+    } else if (result < 0) {
+        return std::strong_ordering::less;
+    } else {
+        return std::strong_ordering::greater;
+    }
+}
+#endif
+
 inline String8::operator const char*() const
 {
     return mString;
diff --git a/mkbootfs/mkbootfs.c b/mkbootfs/mkbootfs.c
index d3922bf..84a0a4e 100644
--- a/mkbootfs/mkbootfs.c
+++ b/mkbootfs/mkbootfs.c
@@ -402,7 +402,7 @@
 static void usage(void)
 {
     fprintf(stderr,
-            "Usage: mkbootfs [-n FILE] [-d DIR|-F FILE] DIR...\n"
+            "Usage: mkbootfs [-n FILE] [-d DIR|-f FILE] DIR...\n"
             "\n"
             "\t-d, --dirname=DIR: fs-config directory\n"
             "\t-f, --file=FILE: Canned configuration file\n"
@@ -410,11 +410,11 @@
             "\t-n, --nodes=FILE: Dev nodes description file\n"
             "\n"
             "Dev nodes description:\n"
-            "\t[dir|nod] [perms] [uid] [gid] [c|b] [minor] [major]\n"
+            "\t[dir|nod] [perms] [uid] [gid] [c|b] [major] [minor]\n"
             "\tExample:\n"
             "\t\t# My device nodes\n"
             "\t\tdir dev 0755 0 0\n"
-            "\t\tnod dev/null 0600 0 0 c 1 5\n"
+            "\t\tnod dev/null 0600 0 0 c 1 3\n"
     );
 }
 
@@ -445,11 +445,6 @@
     int num_dirs = argc - optind;
     argv += optind;
 
-    if (num_dirs <= 0) {
-        usage();
-        errx(1, "no directories to process?!");
-    }
-
     while(num_dirs-- > 0){
         char *x = strchr(*argv, '=');
         if(x != 0) {