From 1f9761f523d661167fce35120e79c84ed27f0d8f Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Tue, 23 Sep 2025 16:46:29 +0300 Subject: [PATCH] Log to the Android logd service where appropriate Add logging macros and use them. The implementation of the macros uses the Android logging library if available, otherwise they use the standard error output. --- CMakeLists.txt | 18 ++++++++++++++++ meson.build | 6 ++++++ src/alloc.c | 5 +++-- src/loader-static.c | 9 ++++---- src/loader.c | 19 +++++++++-------- src/logging-private.h | 48 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 src/logging-private.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a01daf8..fb863792 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.5) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(VersioningUtils) +include(CheckIncludeFile) + read_version_header("" "WPE_[A-Z]+_VERSION" "${CMAKE_CURRENT_SOURCE_DIR}/include/wpe/libwpe-version.h") set_project_version(${WPE_MAJOR_VERSION} ${WPE_MINOR_VERSION} ${WPE_MICRO_VERSION}) set(WPE_API_VERSION "1.0") @@ -129,6 +131,22 @@ if (WPE_ENABLE_XKB) set(WPE_PC_REQUIRES xkbcommon) endif () +check_include_file("android/log.h" HAVE_ANDROID_LOG_H) +if (HAVE_ANDROID_LOG_H) + include(CMakePushCheckState) + include(CheckFunctionExists) + + cmake_push_check_state(RESET) + list(APPEND CMAKE_REQUIRED_LIBRARIES -llog) + check_function_exists(__android_log_print HAVE_ANDROID_LOG_PRINT) + cmake_pop_check_state() + + if (HAVE_ANDROID_LOG_PRINT) + target_compile_definitions(wpe PRIVATE WPE_ENABLE_ANDROID=1) + target_link_libraries(wpe PRIVATE -llog) + endif () +endif () + install( TARGETS wpe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/meson.build b/meson.build index 917e8564..38a71a8d 100644 --- a/meson.build +++ b/meson.build @@ -76,6 +76,12 @@ if not cc.has_function('dlopen') dependencies += dl_dep endif +android_log_lib = cc.find_library('log', has_headers: ['android/log.h'], required: false) +if android_log_lib.found() + add_project_arguments('-DWPE_ENABLE_ANDROID=1', language: ['c', 'cpp']) + dependencies += [android_log_lib] +endif + if pkg_cflags.length() > 0 add_project_arguments(pkg_cflags, language: ['c', 'cpp']) endif diff --git a/src/alloc.c b/src/alloc.c index 83b34173..f3bb63d0 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -28,10 +28,11 @@ #include +#include "logging-private.h" + void wpe_alloc_fail(const char* file, unsigned line, size_t amount) { - fprintf(stderr, "%s:%u: failed to allocate %zu bytes\n", file, line, amount); - fflush(stderr); + wpe_log_fatal("%s:%u: failed to allocate %zu bytes", file, line, amount); abort(); } diff --git a/src/loader-static.c b/src/loader-static.c index e195bcf7..7470852b 100644 --- a/src/loader-static.c +++ b/src/loader-static.c @@ -26,9 +26,10 @@ #include "loader-private.h" -#include #include +#include "logging-private.h" + extern struct wpe_loader_interface _wpe_loader_interface; bool @@ -51,9 +52,9 @@ void* wpe_load_object(const char* object_name) { if (!_wpe_loader_interface.load_object) { - fprintf(stderr, - "wpe_load_object: failed to load object with name '%s': backend doesn't implement load_object vfunc\n", - object_name); + wpe_log_fatal( + "wpe_load_object: failed to load object with name '%s': backend doesn't implement load_object vfunc", + object_name); abort(); } return _wpe_loader_interface.load_object(object_name); diff --git a/src/loader.c b/src/loader.c index 9e22061c..2772e7ca 100644 --- a/src/loader.c +++ b/src/loader.c @@ -31,6 +31,7 @@ #include #include "alloc-private.h" +#include "logging-private.h" static void* s_impl_library = 0; static struct wpe_loader_interface* s_impl_loader = 0; @@ -68,7 +69,7 @@ load_impl_library() #ifdef WPE_BACKEND s_impl_library = dlopen(WPE_BACKEND, RTLD_NOW); if (!s_impl_library) { - fprintf(stderr, "wpe: could not load compile-time defined WPE_BACKEND: %s\n", dlerror()); + wpe_log_fatal("could not load compile-time defined WPE_BACKEND: %s", dlerror()); abort(); } #else @@ -78,7 +79,7 @@ load_impl_library() if (env_library_name) { s_impl_library = dlopen(env_library_name, RTLD_NOW); if (!s_impl_library) { - fprintf(stderr, "wpe: could not load specified WPE_BACKEND_LIBRARY: %s\n", dlerror()); + wpe_log_fatal("could not load specified WPE_BACKEND_LIBRARY: %s", dlerror()); abort(); } wpe_loader_set_impl_library_name(env_library_name); @@ -88,7 +89,7 @@ load_impl_library() // Load libWPEBackend-default.so by ... default. s_impl_library = dlopen("libWPEBackend-default.so", RTLD_NOW); if (!s_impl_library) { - fprintf(stderr, "wpe: could not load the impl library. Is there any backend installed?: %s\n", dlerror()); + wpe_log_fatal("could not load the impl library. Is there any backend installed?: %s", dlerror()); abort(); } wpe_loader_set_impl_library_name("libWPEBackend-default.so"); @@ -103,13 +104,13 @@ wpe_loader_init(const char* impl_library_name) { #ifndef WPE_BACKEND if (!impl_library_name) { - fprintf(stderr, "wpe_loader_init: invalid implementation library name\n"); + wpe_log_fatal("wpe_loader_init: invalid implementation library name"); abort(); } if (s_impl_library) { if (!s_impl_library_name || strcmp(s_impl_library_name, impl_library_name) != 0) { - fprintf(stderr, "wpe_loader_init: already initialized\n"); + wpe_log_fatal("wpe_loader_init: already initialized"); return false; } return true; @@ -117,7 +118,7 @@ wpe_loader_init(const char* impl_library_name) s_impl_library = dlopen(impl_library_name, RTLD_NOW); if (!s_impl_library) { - fprintf(stderr, "wpe_loader_init could not load the library '%s': %s\n", impl_library_name, dlerror()); + wpe_log_error("wpe_loader_init could not load the library '%s': %s", impl_library_name, dlerror()); return false; } wpe_loader_set_impl_library_name(impl_library_name); @@ -147,7 +148,9 @@ wpe_load_object(const char* object_name) if (s_impl_loader) { if (!s_impl_loader->load_object) { - fprintf(stderr, "wpe_load_object: failed to load object with name '%s': backend doesn't implement load_object vfunc\n", object_name); + wpe_log_fatal( + "wpe_load_object: failed to load object with name '%s': backend doesn't implement load_object vfunc", + object_name); abort(); } return s_impl_loader->load_object(object_name); @@ -155,7 +158,7 @@ wpe_load_object(const char* object_name) void* object = dlsym(s_impl_library, object_name); if (!object) - fprintf(stderr, "wpe_load_object: failed to load object with name '%s'\n", object_name); + wpe_log_error("wpe_load_object: failed to load object with name '%s'", object_name); return object; } diff --git a/src/logging-private.h b/src/logging-private.h new file mode 100644 index 00000000..7deb1b5d --- /dev/null +++ b/src/logging-private.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2025 Igalia S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if defined(WPE_ENABLE_ANDROID) && WPE_ENABLE_ANDROID +#include + +#define wpe_log(level, fmt, ...) __android_log_print(ANDROID_LOG_##level, "libwpe", (fmt), ##__VA_ARGS__) + +#else +#include + +#define wpe_log(level, fmt, ...) \ + do { \ + fprintf(stderr, "libwpe [" #level "]: " fmt "\n", ##__VA_ARGS__); \ + fflush(stderr); \ + } while (0) + +#endif + +#define wpe_log_debug(fmt, ...) wpe_log(DEBUG, fmt, ##__VA_ARGS__) +#define wpe_log_warning(fmt, ...) wpe_log(WARN, fmt, ##__VA_ARGS__) +#define wpe_log_error(fmt, ...) wpe_log(ERROR, fmt, ##__VA_ARGS__) +#define wpe_log_fatal(fmt, ...) wpe_log(FATAL, fmt, ##__VA_ARGS__)