From 94bdcf556e50727f4d5be9875e8c3741ec632f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Pelczar?= Date: Tue, 13 Aug 2024 16:33:14 +0200 Subject: [PATCH] android: Support __android_log_write_log_message based logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function has been introduced in API Level 30. This commit enables support for dynamic use of the new API (in case the application would run on older OS versions). Signed-off-by: Jarosław Pelczar --- include/spdlog/sinks/android_sink.h | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index 4435a560a..e8f303c66 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -22,6 +22,10 @@ #define SPDLOG_ANDROID_RETRIES 2 #endif + #if __ANDROID_API__ >= 30 + #define SPDLOG_ANDROID_ENABLE_LOG_WRITE + #endif + namespace spdlog { namespace sinks { @@ -35,7 +39,12 @@ class android_sink final : public base_sink { public: explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false) : tag_(std::move(tag)), - use_raw_msg_(use_raw_msg) {} + use_raw_msg_(use_raw_msg) { + // Available since API level 30 + #ifdef SPDLOG_ANDROID_ENABLE_LOG_WRITE + write_message_ = (write_log_message_t)dlsym(nullptr, "__android_log_write_log_message"); + #endif + } protected: void sink_it_(const details::log_msg &msg) override { @@ -49,6 +58,21 @@ class android_sink final : public base_sink { formatted.push_back('\0'); const char *msg_output = formatted.data(); + #ifdef SPDLOG_ANDROID_ENABLE_LOG_WRITE + if (write_message_) { + __android_log_message logMessage{}; + logMessage.struct_size = sizeof(logMessage); + logMessage.buffer_id = BufferID; + logMessage.priority = priority; + logMessage.tag = tag_.c_str(); + logMessage.file = msg.source.filename; + logMessage.line = static_cast(msg.source.line); + logMessage.message = msg_output; + write_message_(&logMessage); + return; + } + #endif + // See system/core/liblog/logger_write.c for explanation of return value int ret = android_log(priority, tag_.c_str(), msg_output); if (ret == -EPERM) { @@ -104,8 +128,15 @@ class android_sink final : public base_sink { } } + #ifdef SPDLOG_ANDROID_ENABLE_LOG_WRITE + typedef void (*write_log_message_t)(struct __android_log_message *log_message); + #endif + std::string tag_; bool use_raw_msg_; + #ifdef SPDLOG_ANDROID_ENABLE_LOG_WRITE + write_log_message_t write_message_; + #endif }; using android_sink_mt = android_sink;