Merge "libstatssocket_lazy: add isAvailable()" into main
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());
+}