From: Manuel Bachmann Date: Wed, 10 Sep 2014 14:48:55 +0000 (+0200) Subject: Introduce the display plugin system X-Git-Tag: accepted/tizen/common/20140912.142546^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0a2700ea5288a37c1eaf90fd97116037db4d634b;p=platform%2Fcore%2Fappfw%2Fnotification-service.git Introduce the display plugin system At startup, "notification-display-service" will now search for plugins in the "/usr/lib$ARCH/notification-service /plugins" directory. If one is found, it will use it to display notifications on screens. Otherwise, it will fall back to pure text with dlog. There is currently one plugin : wlmessage.so. Change-Id: I663fc24ec2c9fd8c1f0a2f07be08f479f2a4569d Signed-off-by: Manuel Bachmann --- diff --git a/Makefile.am b/Makefile.am index 3ff5d19..532cab3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,10 @@ +SUBDIRS = plugins +moduledir = $(libdir)/notification-service/plugins + bin_PROGRAMS = notification-service notification-display-service sample-display-client send-notification bluetooth_notification_client AM_CFLAGS = $(GCC_CFLAGS) -AM_CPPFLAGS = $(GCC_CFLAGS) +AM_CPPFLAGS = $(GCC_CFLAGS) -DPLUGINSDIR='"$(moduledir)"' notification_service_SOURCES = \ main.c \ @@ -12,7 +15,7 @@ notification_service_LDADD = $(TIZEN_LIBS) notification_display_service_SOURCES = notification_display_service.c notification_display_service_CFLAGS = -I. $(TIZEN_CFLAGS) -notification_display_service_LDADD = $(TIZEN_LIBS) +notification_display_service_LDADD = $(TIZEN_LIBS) $(DLOPEN_LIBS) send_notification_SOURCES = send_notification.c send_notification_CFLAGS = -I. $(TIZEN_CFLAGS) diff --git a/configure.ac b/configure.ac index edb8edb..2987c6b 100644 --- a/configure.ac +++ b/configure.ac @@ -10,10 +10,15 @@ LT_PREREQ([2.2]) LT_INIT([disable-static]) PKG_PROG_PKG_CONFIG() + +AC_CHECK_FUNC([dlopen], [], + AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) +AC_SUBST(DLOPEN_LIBS) + PKG_CHECK_MODULES([TIZEN], [eina ecore com-core notification dbus-1 bluetooth-api dlog libwlmessage]) AC_SUBST(TIZEN_CFLAGS) AC_SUBST(TIZEN_LIBS) -AC_CONFIG_FILES([Makefile notifications.service notifications-display.service]) +AC_CONFIG_FILES([Makefile plugins/Makefile notifications.service notifications-display.service]) AC_PROG_RANLIB([ranlib]) AC_OUTPUT diff --git a/notification_display_service.c b/notification_display_service.c index df35e42..30211ac 100644 --- a/notification_display_service.c +++ b/notification_display_service.c @@ -1,66 +1,110 @@ #include -#include +#include #include +#include #include +#include #include -#include -void display_notifications_cb (void *data, notification_type_e notif_type) +void load_plugins (char *path, int (**fct)(notification_h)) { - notification_h noti = NULL; - notification_list_h notification_list = NULL; - notification_list_h get_list = NULL; + DIR *dir; + struct dirent *plugins_dir; + char *plugin_path; + void *plugin; + int (*plugin_fct)(notification_h); + + dir = opendir (path); + if (!dir) + return; + + while ((plugins_dir = readdir(dir)) != NULL) { + if (g_str_has_suffix (plugins_dir->d_name, ".so")) { + plugin_path = g_strconcat (path, G_DIR_SEPARATOR_S, plugins_dir->d_name, NULL); + plugin = dlopen (plugin_path, RTLD_NOW | RTLD_LOCAL); + plugin_fct = dlsym (plugin, "display_notification"); + g_free (plugin_path); + if (!plugin) { + LOGD("\"%s\" is not a plugin, continuing", plugins_dir->d_name); + continue; + } else if (!plugin_fct) { + LOGD("Plugin \"%s\" incompatible, continuing", plugins_dir->d_name); + dlclose (plugins_dir->d_name); + continue; + } else { + /* use the first working plugin, if not configured otherwise */ + LOGD("Plugin \"%s\" compatible, loading...", plugins_dir->d_name); + *fct = plugin_fct; + break; + } + } + } + + closedir (dir); +} +int display_notification_text (notification_h noti) +{ char *pkgname = NULL; char *title = NULL; char *content = NULL; char *image_path = NULL; + notification_get_pkgname (noti, &pkgname); + if (pkgname == NULL) + notification_get_application (noti, &pkgname); + notification_get_title (noti, &title, NULL); + notification_get_text (noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content); + notification_get_image (noti, NOTIFICATION_IMAGE_TYPE_ICON, &image_path); + + LOGD("\nNew Notification : %s", title); + LOGD("Icon : %s", image_path); + LOGD("Message : %s", content); + + return 1; +} + +void display_notifications_cb (void *data, notification_type_e notif_type) +{ + int (*fct)(notification_h) = data; + notification_h noti = NULL; + notification_list_h notification_list = NULL; + notification_list_h get_list = NULL; + notification_get_list (NOTIFICATION_TYPE_NOTI, -1, ¬ification_list); if (notification_list) { get_list = notification_list_get_head (notification_list); while (get_list) { noti = notification_list_get_data (get_list); - notification_get_pkgname (noti, &pkgname); - if (pkgname == NULL) - notification_get_application (noti, &pkgname); - notification_get_title (noti, &title, NULL); - notification_get_text (noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content); - notification_get_image (noti, NOTIFICATION_IMAGE_TYPE_ICON, &image_path); - - struct wlmessage *wlmessage = wlmessage_create (); - wlmessage_set_title (wlmessage, title); - wlmessage_set_icon (wlmessage, image_path); - wlmessage_set_message (wlmessage, content); - wlmessage_add_button (wlmessage, 0, "Ok"); - if (wlmessage_show (wlmessage, NULL) < 0) { - wlmessage_destroy (wlmessage); - return; - } - wlmessage_destroy (wlmessage); - - LOGD("\nNew Notification : %s\n", title); - LOGD("Icon : %s\n", image_path); - LOGD("Message : %s\n", content); - get_list = notification_list_remove(get_list, noti); - notification_delete(noti); + /* if the display function was successful, delete the notification */ + if ( (*fct)(noti) ) { + get_list = notification_list_remove(get_list, noti); + notification_delete(noti); + } } } } + int main (int argc, char **argv) { GMainLoop *mainloop = NULL; + gboolean error_s; notification_error_e error_n; - int error_s; - struct stat buf; + int (*disp_fct)(notification_h); + + /* fall back to pure text notification if no plugin works */ + disp_fct = &display_notification_text; + LOGD("Checking for display plugins..."); + if (g_file_test (PLUGINSDIR, G_FILE_TEST_IS_DIR)) + load_plugins (PLUGINSDIR, &disp_fct); retry_socket: LOGD("Checking if the notifications server socket exists..."); - error_s = stat ("/tmp/.notification.service", &buf); - if (error_s == -1) { + error_s = g_file_test ("/tmp/.notification.service", G_FILE_TEST_EXISTS); + if (!error_s) { LOGD("Could not find the notifications server socket"); sleep (5); goto retry_socket; @@ -68,7 +112,7 @@ retry_socket: retry_service: LOGD("Checking if the notifications server is available..."); - error_n = notification_resister_changed_cb (display_notifications_cb, NULL); + error_n = notification_resister_changed_cb (display_notifications_cb, (*disp_fct)); if (error_n != NOTIFICATION_ERROR_NONE) { LOGD("Could not register with notifications server"); sleep (5); diff --git a/packaging/notification-service.spec b/packaging/notification-service.spec index cc557c6..68dd000 100644 --- a/packaging/notification-service.spec +++ b/packaging/notification-service.spec @@ -56,6 +56,7 @@ make %{?_smp_mflags} %defattr(-,root,root,-) %{_bindir}/notification-service %{_bindir}/notification-display-service +%{_libdir}/notification-service/plugins/wlmessage.so %{_unitdir}/notifications.service %{_unitdir}/notifications-display.service %{_unitdir}/graphical.target.wants/notifications.service diff --git a/plugins/Makefile.am b/plugins/Makefile.am new file mode 100644 index 0000000..0d2c4b7 --- /dev/null +++ b/plugins/Makefile.am @@ -0,0 +1,14 @@ +bin_PROGRAMS = +moduledir = $(libdir)/notification-service/plugins + +AM_CFLAGS = $(GCC_CFLAGS) +AM_CPPFLAGS = $(GCC_CFLAGS) + +module_LTLIBRARIES = wlmessage.la + +wlmessage_la_SOURCES = wlmessage.c + +wlmessage_la_LDFLAGS = -module -avoid-version +wlmessage_la_CPPFLAGS = $(AM_CPPFLAGS) +wlmessage_la_CFLAGS = $(TIZEN_CFLAGS) +wlmessage_la_LIBADD = $(TIZEN_LIBS) diff --git a/plugins/wlmessage.c b/plugins/wlmessage.c new file mode 100644 index 0000000..6f691af --- /dev/null +++ b/plugins/wlmessage.c @@ -0,0 +1,30 @@ +#include +#include + + +int display_notification (notification_h noti) +{ + char *pkgname = NULL; + char *title = NULL; + char *content = NULL; + char *image_path = NULL; + + notification_get_pkgname (noti, &pkgname); + if (pkgname == NULL) + notification_get_application (noti, &pkgname); + notification_get_title (noti, &title, NULL); + notification_get_text (noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content); + notification_get_image (noti, NOTIFICATION_IMAGE_TYPE_ICON, &image_path); + + struct wlmessage *wlmessage = wlmessage_create (); + wlmessage_set_title (wlmessage, title); + wlmessage_set_icon (wlmessage, image_path); + wlmessage_set_message (wlmessage, content); + wlmessage_add_button (wlmessage, 0, "Ok"); + if (wlmessage_show (wlmessage, NULL) < 0) { + wlmessage_destroy (wlmessage); + return 0; + } + + return 1; +}