Android: implement chained log callbacks (buffer and terminal output)
authorGerhard Sittig <gerhard.sittig@gmx.net>
Mon, 20 Aug 2018 16:57:25 +0000 (18:57 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Thu, 30 Aug 2018 17:17:20 +0000 (19:17 +0200)
Query the libraries' default log handlers before registering the
application's own handler. Queue log messages in the application's
internal buffer _and_ hand them to the default handlers which send
the text to stdout as well.

android/loghandler.cpp

index 137d2dff8f7a0e09ae7c5629a22c9bef7052441b..c9953a6e2894e21e924e99d8ffa4fbefa2b8efb7 100644 (file)
 
 namespace pv {
 
 
 namespace pv {
 
+static sr_log_callback prev_sr_log_cb;
+static void *prev_sr_log_cb_data;
+
+#ifdef ENABLE_DECODE
+static srd_log_callback prev_srd_log_cb;
+static void *prev_srd_log_cb_data;
+#endif
+
 int AndroidLogHandler::sr_callback(void *cb_data, int loglevel, const char *format, va_list args)
 {
        static const int prio[] = {
 int AndroidLogHandler::sr_callback(void *cb_data, int loglevel, const char *format, va_list args)
 {
        static const int prio[] = {
@@ -40,11 +48,18 @@ int AndroidLogHandler::sr_callback(void *cb_data, int loglevel, const char *form
                [SR_LOG_DBG] = ANDROID_LOG_DEBUG,
                [SR_LOG_SPEW] = ANDROID_LOG_VERBOSE,
        };
                [SR_LOG_DBG] = ANDROID_LOG_DEBUG,
                [SR_LOG_SPEW] = ANDROID_LOG_VERBOSE,
        };
+       va_list args2;
        int ret;
 
        /* This specific log callback doesn't need the void pointer data. */
        (void)cb_data;
 
        int ret;
 
        /* This specific log callback doesn't need the void pointer data. */
        (void)cb_data;
 
+       /* Call the previously registered log callback (library's default). */
+       va_copy(args2, args);
+       if (prev_sr_log_cb)
+               prev_sr_log_cb(prev_sr_log_cb_data, loglevel, format, args2);
+       va_end(args2);
+
        /* Only output messages of at least the selected loglevel(s). */
        if (loglevel > sr_log_loglevel_get())
                return SR_OK;
        /* Only output messages of at least the selected loglevel(s). */
        if (loglevel > sr_log_loglevel_get())
                return SR_OK;
@@ -70,11 +85,18 @@ int AndroidLogHandler::srd_callback(void *cb_data, int loglevel, const char *for
                [SRD_LOG_DBG] = ANDROID_LOG_DEBUG,
                [SRD_LOG_SPEW] = ANDROID_LOG_VERBOSE,
        };
                [SRD_LOG_DBG] = ANDROID_LOG_DEBUG,
                [SRD_LOG_SPEW] = ANDROID_LOG_VERBOSE,
        };
+       va_list args2;
        int ret;
 
        /* This specific log callback doesn't need the void pointer data. */
        (void)cb_data;
 
        int ret;
 
        /* This specific log callback doesn't need the void pointer data. */
        (void)cb_data;
 
+       /* Call the previously registered log callback (library's default). */
+       va_copy(args2, args);
+       if (prev_srd_log_cb)
+               prev_srd_log_cb(prev_srd_log_cb_data, loglevel, format, args2);
+       va_end(args2);
+
        /* Only output messages of at least the selected loglevel(s). */
        if (loglevel > srd_log_loglevel_get())
                return SRD_OK;
        /* Only output messages of at least the selected loglevel(s). */
        if (loglevel > srd_log_loglevel_get())
                return SRD_OK;
@@ -94,8 +116,10 @@ int AndroidLogHandler::srd_callback(void *cb_data, int loglevel, const char *for
 
 void AndroidLogHandler::install_callbacks()
 {
 
 void AndroidLogHandler::install_callbacks()
 {
+       sr_log_callback_get(&prev_sr_log_cb, &prev_sr_log_cb_data);
        sr_log_callback_set(sr_callback, nullptr);
 #ifdef ENABLE_DECODE
        sr_log_callback_set(sr_callback, nullptr);
 #ifdef ENABLE_DECODE
+       srd_log_callback_get(&prev_srd_log_cb, &prev_srd_log_cb_data);
        srd_log_callback_set(srd_callback, nullptr);
 #endif
 }
        srd_log_callback_set(srd_callback, nullptr);
 #endif
 }