From aff070bcbb771a5096f02b60c84aacfde601e043 Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Sun, 2 Nov 2014 16:52:43 +0100 Subject: [PATCH] android: add LogListener A Java object to send logs on the android side. --- Makefile.am | 3 ++- android/src/Bridge.java | 8 ++++++- android/src/Main.java | 2 +- src/LogBackend.cxx | 5 ++++ src/Main.cxx | 7 +++++- src/Main.hxx | 3 +++ src/android/LogListener.cxx | 46 +++++++++++++++++++++++++++++++++++++ src/android/LogListener.hxx | 32 ++++++++++++++++++++++++++ 8 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 src/android/LogListener.cxx create mode 100644 src/android/LogListener.hxx diff --git a/Makefile.am b/Makefile.am index de091bdd5..495157e78 100644 --- a/Makefile.am +++ b/Makefile.am @@ -276,7 +276,8 @@ libjava_a_SOURCES = \ noinst_LIBRARIES += libandroid.a libandroid_a_SOURCES = \ src/android/Context.cxx src/android/Context.hxx \ - src/android/Environment.cxx src/android/Environment.hxx + src/android/Environment.cxx src/android/Environment.hxx \ + src/android/LogListener.cxx src/android/LogListener.hxx libandroid_a_CPPFLAGS = $(AM_CPPFLAGS) -Iandroid/build/include noinst_LIBRARIES += libmain.a diff --git a/android/src/Bridge.java b/android/src/Bridge.java index be8eabb6b..fad919204 100644 --- a/android/src/Bridge.java +++ b/android/src/Bridge.java @@ -25,6 +25,12 @@ import android.content.Context; * Bridge to native code. */ public class Bridge { - public static native void run(Context context); + + /* used by jni */ + public interface LogListener { + public void onLog(int priority, String msg); + } + + public static native void run(Context context, LogListener logListener); public static native void shutdown(); } diff --git a/android/src/Main.java b/android/src/Main.java index da64a1976..816b62cdb 100644 --- a/android/src/Main.java +++ b/android/src/Main.java @@ -69,7 +69,7 @@ public class Main extends Activity implements Runnable { } @Override public void run() { - Bridge.run(this); + Bridge.run(this, null); quitHandler.sendMessage(quitHandler.obtainMessage()); } } diff --git a/src/LogBackend.cxx b/src/LogBackend.cxx index ea3d2e2d6..323bcae91 100644 --- a/src/LogBackend.cxx +++ b/src/LogBackend.cxx @@ -34,6 +34,8 @@ #ifdef ANDROID #include +#include "android/LogListener.hxx" +#include "Main.hxx" static int ToAndroidLogLevel(LogLevel log_level) @@ -177,6 +179,9 @@ Log(const Domain &domain, LogLevel level, const char *msg) #ifdef ANDROID __android_log_print(ToAndroidLogLevel(level), "MPD", "%s: %s", domain.GetName(), msg); + if (logListener != nullptr) + logListener->OnLog(Java::GetEnv(), ToAndroidLogLevel(level), + "%s: %s", domain.GetName(), msg); #else if (level < log_threshold) diff --git a/src/Main.cxx b/src/Main.cxx index 31c4d9fbd..f8fe3e93f 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -92,6 +92,7 @@ #include "java/File.hxx" #include "android/Environment.hxx" #include "android/Context.hxx" +#include "android/LogListener.hxx" #include "fs/StandardDirectory.hxx" #include "fs/FileSystem.hxx" #include "org_musicpd_Bridge.h" @@ -128,6 +129,7 @@ static constexpr unsigned DEFAULT_BUFFER_BEFORE_PLAY = 10; #ifdef ANDROID Context *context; +LogListener *logListener; #endif Instance *instance; @@ -676,16 +678,19 @@ try { gcc_visibility_default JNIEXPORT void JNICALL -Java_org_musicpd_Bridge_run(JNIEnv *env, jclass, jobject _context) +Java_org_musicpd_Bridge_run(JNIEnv *env, jclass, jobject _context, jobject _logListener) { Java::Init(env); Java::File::Initialise(env); Environment::Initialise(env); context = new Context(env, _context); + if (_logListener != nullptr) + logListener = new LogListener(env, _logListener); mpd_main(0, nullptr); + delete logListener; delete context; Environment::Deinitialise(env); } diff --git a/src/Main.hxx b/src/Main.hxx index 9b41abf9f..f54b27767 100644 --- a/src/Main.hxx +++ b/src/Main.hxx @@ -25,7 +25,10 @@ class Context; struct Instance; #ifdef ANDROID +#include "android/LogListener.hxx" + extern Context *context; +extern LogListener *logListener; #endif extern Instance *instance; diff --git a/src/android/LogListener.cxx b/src/android/LogListener.cxx new file mode 100644 index 000000000..c7fed8811 --- /dev/null +++ b/src/android/LogListener.cxx @@ -0,0 +1,46 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "LogListener.hxx" +#include "java/Class.hxx" +#include "java/String.hxx" +#include "util/AllocatedString.hxx" +#include "util/FormatString.hxx" + +void +LogListener::OnLog(JNIEnv *env, int priority, const char *fmt, ...) const +{ + assert(env != nullptr); + + Java::Class cls(env, env->GetObjectClass(Get())); + + jmethodID method = env->GetMethodID(cls, "onLog", + "(ILjava/lang/String;)V"); + + assert(method); + + va_list args; + va_start(args, fmt); + const auto log = FormatStringV(fmt, args); + va_end(args); + + env->CallVoidMethod(Get(), method, priority, + Java::String(env, log.c_str()).Get()); +} diff --git a/src/android/LogListener.hxx b/src/android/LogListener.hxx new file mode 100644 index 000000000..2c81078fe --- /dev/null +++ b/src/android/LogListener.hxx @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ANDROID_LOG_LISTENER_HXX +#define MPD_ANDROID_LOG_LISTENER_HXX + +#include "java/Object.hxx" + +class LogListener : public Java::Object { +public: + LogListener(JNIEnv *env, jobject obj):Java::Object(env, obj) {} + + void OnLog(JNIEnv *env, int priority, const char *fmt, ...) const; +}; + +#endif