diff --git a/android/app/src/main/java/org/musicpd/Bridge.java b/android/app/src/main/java/org/musicpd/Bridge.java index 6ad49e2d4a..a67175d1c1 100644 --- a/android/app/src/main/java/org/musicpd/Bridge.java +++ b/android/app/src/main/java/org/musicpd/Bridge.java @@ -5,6 +5,8 @@ import android.content.Context; +import org.musicpd.models.SongInfo; + /** * Bridge to native code. */ @@ -18,4 +20,7 @@ public interface LogListener { public static native void run(Context context, LogListener logListener); public static native void shutdown(); public static native void pause(); + public static native void playNext(); + public static native void playPrevious(); + public static native SongInfo currentSong(); } diff --git a/android/app/src/main/java/org/musicpd/models/SongInfo.java b/android/app/src/main/java/org/musicpd/models/SongInfo.java new file mode 100644 index 0000000000..dd9a037e3b --- /dev/null +++ b/android/app/src/main/java/org/musicpd/models/SongInfo.java @@ -0,0 +1,9 @@ +package org.musicpd.models; + +import java.util.HashMap; + +public class SongInfo { + String uri; + int durationMilliseconds; + HashMap tags; +} diff --git a/android/include/meson.build b/android/include/meson.build index af9f57ebf4..cce8b5394c 100644 --- a/android/include/meson.build +++ b/android/include/meson.build @@ -5,6 +5,7 @@ bridge_header = custom_target( output: 'org_musicpd_Bridge.h', input: [ '../app/src/main/java/org/musicpd/Bridge.java', + '../app/src/main/java/org/musicpd/models/SongInfo.java', ], command: [ javac, diff --git a/meson.build b/meson.build index d56f64505e..8240e462b4 100644 --- a/meson.build +++ b/meson.build @@ -438,6 +438,7 @@ else 'src/android/AudioManager.cxx', 'src/android/Environment.cxx', 'src/android/LogListener.cxx', + 'src/android/Song.cxx', ] endif diff --git a/src/Main.cxx b/src/Main.cxx index 4a469bc4f7..fdf3a97329 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -79,6 +79,7 @@ #include "android/Environment.hxx" #include "android/Context.hxx" #include "android/LogListener.hxx" +#include "android/Song.hxx" #include "config/File.hxx" #include "fs/FileSystem.hxx" #include "org_musicpd_Bridge.h" @@ -614,6 +615,38 @@ Java_org_musicpd_Bridge_pause(JNIEnv *, jclass) partition.pc.LockSetPause(true); } +gcc_visibility_default +JNIEXPORT void JNICALL +Java_org_musicpd_Bridge_playNext(JNIEnv *, jclass) +{ + +} + +gcc_visibility_default +JNIEXPORT void JNICALL +Java_org_musicpd_Bridge_playPrevious(JNIEnv *, jclass) +{ + +} + +gcc_visibility_default +JNIEXPORT jobject JNICALL +Java_org_musicpd_Bridge_currentSong(JNIEnv *env, jclass) +{ + if (global_instance != nullptr) { + for (auto &partition : global_instance->partitions) { + int current_position = partition.playlist.GetCurrentPosition(); + if (current_position < 0) + continue; + + std::unique_ptr song = std::make_unique(partition.playlist.queue.Get(current_position)); + return song_to_song_info(env, song); + } + } + + return NULL; +} + #else static inline void diff --git a/src/android/Song.cxx b/src/android/Song.cxx new file mode 100644 index 0000000000..c8205e0947 --- /dev/null +++ b/src/android/Song.cxx @@ -0,0 +1,46 @@ +#include "Song.hxx" +#include "java/Class.hxx" +#include "tag/Names.hxx" + +jobject song_to_song_info(JNIEnv *env, std::unique_ptr &song) { + jobject tag_map = song_to_tag_hashmap(env, song); + + Java::Class cls(env, "org/musicpd/models/SongInfo"); + jmethodID init = env->GetMethodID(cls, "", "()V"); + jobject song_info = env->NewObject(cls, init); + + jstring uri = env->NewStringUTF(song->GetURI()); + jfieldID id_uri = env->GetFieldID(cls, "uri", "Ljava/lang/String;"); + env->SetObjectField(song_info, id_uri, uri); + env->DeleteLocalRef(uri); + + const auto duration = song->GetDuration(); + jfieldID id_duration = env->GetFieldID(cls, "durationMilliseconds", "I"); + env->SetIntField(song_info, id_duration, duration.ToMS()); + + jfieldID id_tags = env->GetFieldID(cls, "tags", "Ljava/util/HashMap;"); + env->SetObjectField(song_info, id_tags, tag_map); + env->DeleteLocalRef(tag_map); + + return song_info; +} + +jobject song_to_tag_hashmap(JNIEnv *env, std::unique_ptr &song) { + Java::Class cls(env, "java/util/HashMap"); + jmethodID init = env->GetMethodID(cls, "", "()V"); + jobject hash_map = env->NewObject(cls, init); + jmethodID put = env->GetMethodID(cls, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + const Tag &tag = song->GetTag(); + for (const auto &i : tag) { + jstring key = env->NewStringUTF(tag_item_names[i.type]); + jstring value = env->NewStringUTF(i.value); + + env->CallObjectMethod(hash_map, put, key, value); + + env->DeleteLocalRef(key); + env->DeleteLocalRef(value); + } + + return hash_map; +} \ No newline at end of file diff --git a/src/android/Song.hxx b/src/android/Song.hxx new file mode 100644 index 0000000000..3946e2dda8 --- /dev/null +++ b/src/android/Song.hxx @@ -0,0 +1,7 @@ +#include "song/DetachedSong.hxx" + +#include "java/Object.hxx" + +jobject song_to_song_info(JNIEnv *env, std::unique_ptr &song); + +jobject song_to_tag_hashmap(JNIEnv *env, std::unique_ptr &song); \ No newline at end of file