diff --git a/src/api-impl-jni/app/android_app_NotificationManager.c b/src/api-impl-jni/app/android_app_NotificationManager.c index 8c28aeba..beeb0ab2 100644 --- a/src/api-impl-jni/app/android_app_NotificationManager.c +++ b/src/api-impl-jni/app/android_app_NotificationManager.c @@ -1,10 +1,16 @@ +#include #include #include "../defines.h" #include "../util.h" +#include "mpris-dbus.h" + #include "../generated_headers/android_app_NotificationManager.h" +#define MPRIS_BUS_NAME_PREFIX "org.mpris.MediaPlayer2." +#define MPRIS_OBJECT_NAME "/org/mpris/MediaPlayer2" + static XdpPortal *portal = NULL; static GHashTable *ongoing_notifications = NULL; @@ -137,3 +143,45 @@ void remove_ongoing_notifications() if (ongoing_notifications) g_hash_table_foreach(ongoing_notifications, remove_ongoing_notification, NULL); } + +static MediaPlayer2 *mpris = NULL; +extern MediaPlayer2Player *mpris_player; +extern GtkWindow *window; + +static gboolean on_media_player_handle_raise(MediaPlayer2 *mpris, GDBusMethodInvocation *invocation, gpointer user_data) +{ + gtk_window_present(window); + media_player2_complete_raise(mpris, invocation); + return TRUE; +} + +static void on_bus_acquired(GDBusConnection *connection, const char *name, gpointer user_data) +{ + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(mpris), + connection, MPRIS_OBJECT_NAME, NULL); + + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(mpris_player), + connection, MPRIS_OBJECT_NAME, NULL); +} + +JNIEXPORT void JNICALL Java_android_app_NotificationManager_nativeShowMPRIS(JNIEnv *env, jobject this, jstring package_name_jstr, jstring identity_jstr) +{ + if (!mpris) { + mpris = media_player2_skeleton_new(); + g_signal_connect(mpris, "handle-raise", G_CALLBACK(on_media_player_handle_raise), NULL); + + g_bus_own_name(G_BUS_TYPE_SESSION, MPRIS_BUS_NAME_PREFIX "ATL", G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, NULL, NULL, mpris, NULL); + } + media_player2_set_can_raise(mpris, TRUE); + if (package_name_jstr) { + const char *package_name = (*env)->GetStringUTFChars(env, package_name_jstr, NULL); + media_player2_set_desktop_entry(mpris, package_name); + (*env)->ReleaseStringUTFChars(env, package_name_jstr, package_name); + } + if (identity_jstr) { + const char *identity = (*env)->GetStringUTFChars(env, identity_jstr, NULL); + media_player2_set_identity(mpris, identity); + (*env)->ReleaseStringUTFChars(env, identity_jstr, identity); + } +} diff --git a/src/api-impl-jni/generated_headers/android_app_NotificationManager.h b/src/api-impl-jni/generated_headers/android_app_NotificationManager.h index 4adea60f..e1917725 100644 --- a/src/api-impl-jni/generated_headers/android_app_NotificationManager.h +++ b/src/api-impl-jni/generated_headers/android_app_NotificationManager.h @@ -31,6 +31,14 @@ JNIEXPORT void JNICALL Java_android_app_NotificationManager_nativeAddAction JNIEXPORT void JNICALL Java_android_app_NotificationManager_nativeShowNotification (JNIEnv *, jobject, jlong, jint, jstring, jstring, jstring, jboolean, jint, jstring, jstring); +/* + * Class: android_app_NotificationManager + * Method: nativeShowMPRIS + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_android_app_NotificationManager_nativeShowMPRIS + (JNIEnv *, jobject, jstring, jstring); + /* * Class: android_app_NotificationManager * Method: nativeCancel diff --git a/src/api-impl-jni/media/android_media_session_MediaSession.c b/src/api-impl-jni/media/android_media_session_MediaSession.c index 2ed5a568..f70fb64a 100644 --- a/src/api-impl-jni/media/android_media_session_MediaSession.c +++ b/src/api-impl-jni/media/android_media_session_MediaSession.c @@ -6,19 +6,12 @@ #include "../generated_headers/android_media_session_MediaSession.h" #include "../generated_headers/android_os_SystemClock.h" -#define MPRIS_BUS_NAME_PREFIX "org.mpris.MediaPlayer2." #define MPRIS_OBJECT_NAME "/org/mpris/MediaPlayer2" MediaPlayer2Player *mpris_player = NULL; static jobject callback = NULL; static jlong last_position = 0; // playback_position - SystemClock.elapsedRealtime in ms -static void on_bus_acquired(GDBusConnection *connection, const char *name, gpointer user_data) -{ - g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON (mpris_player), - connection, MPRIS_OBJECT_NAME, NULL); -} - static gboolean on_media_player_handle_action(MediaPlayer2Player *mpris_player, GDBusMethodInvocation *invocation, char *method) { if (callback) { @@ -77,8 +70,6 @@ JNIEXPORT void JNICALL Java_android_media_session_MediaSession_nativeSetState(JN "signal::handle-seek", on_media_player_handle_seek, NULL, "signal::handle-set-position", on_media_player_handle_set_position, NULL, NULL); - g_bus_own_name(G_BUS_TYPE_SESSION, MPRIS_BUS_NAME_PREFIX "ATL", G_BUS_NAME_OWNER_FLAGS_NONE, - on_bus_acquired, NULL, NULL, mpris_player, NULL); } media_player2_player_set_playback_status(mpris_player, playback_states[state < 4 ? state : 0]); media_player2_player_set_position(mpris_player, position * 1000); diff --git a/src/api-impl-jni/media/org.mpris.MediaPlayer2.xml b/src/api-impl-jni/media/org.mpris.MediaPlayer2.xml index b977f2a6..ed64b167 100644 --- a/src/api-impl-jni/media/org.mpris.MediaPlayer2.xml +++ b/src/api-impl-jni/media/org.mpris.MediaPlayer2.xml @@ -1,4 +1,10 @@ + + + + + + diff --git a/src/api-impl/android/app/Application.java b/src/api-impl/android/app/Application.java index 0fa422bf..4ed7cad8 100644 --- a/src/api-impl/android/app/Application.java +++ b/src/api-impl/android/app/Application.java @@ -12,7 +12,7 @@ public class Application extends ContextWrapper { return getString(pkg.applicationInfo.icon); } - private String get_app_label() { + String get_app_label() { return getString(pkg.applicationInfo.labelRes); } diff --git a/src/api-impl/android/app/NotificationManager.java b/src/api-impl/android/app/NotificationManager.java index 7d128179..d5231a34 100644 --- a/src/api-impl/android/app/NotificationManager.java +++ b/src/api-impl/android/app/NotificationManager.java @@ -11,8 +11,9 @@ public class NotificationManager { public void cancelAll() {} public void notify(String tag, int id, Notification notification) { - if (notification.style instanceof MediaStyle) { - return; // MPRIS is handled by MediaSession implementation + if (notification.style instanceof MediaStyle) { // MPRIS content is handled by MediaSession implementation + nativeShowMPRIS(Context.this_application.getPackageName(), Context.this_application.get_app_label()); + return; } System.out.println("notify(" + tag + ", " + id + ", " + notification + ") called"); @@ -76,5 +77,6 @@ public class NotificationManager { protected native long nativeInitBuilder(); protected native void nativeAddAction(long builder, String title, int intentType, String action, String className); protected native void nativeShowNotification(long builder, int id, String title, String text, String iconPath, boolean ongoing, int intentType, String action, String className); + protected native void nativeShowMPRIS(String packageName, String identiy); protected native void nativeCancel(int id); }