#include <notification_db.h>
#define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
+#define PROVIDER_NOTI_EVENT_INTERFACE_NAME "org.tizen.data_provider_noti_event_service"
#define NOTI_TEMPLATE_LIMIT 10
#define BUF_LEN 256
alarm_id_t dnd_end_id;
} dnd_alarm_id_s;
+static GHashTable *__event_sender_hash;
+
+typedef struct _event_sender_info {
+ int priv_id;
+ char *busname;
+} event_sender_info_s;
+
/*!
* SERVICE HANDLER
*/
else if (g_strcmp0(method_name, "update_noti") == 0)
ret = notification_update_noti(parameters, &reply_body, uid);
else if (g_strcmp0(method_name, "add_noti") == 0)
- ret = notification_add_noti(parameters, &reply_body, uid);
+ ret = notification_add_noti(parameters, &reply_body, sender, uid);
else if (g_strcmp0(method_name, "refresh_noti") == 0)
ret = notification_refresh_noti(parameters, &reply_body, uid);
else if (g_strcmp0(method_name, "del_noti_single") == 0)
ret = notification_load_dnd_allow_exception(parameters, &reply_body, uid);
else if (g_strcmp0(method_name, "update_dnd_allow_exception") == 0)
ret = notification_update_dnd_allow_exception(parameters, &reply_body, uid);
+ else if (g_strcmp0(method_name, "send_noti_event") == 0)
+ ret = notification_send_noti_event(parameters, &reply_body);
if (ret == NOTIFICATION_ERROR_NONE) {
DbgPrint("notification service success : %d", ret);
ret,
"notification service error");
}
-
}
static const GDBusInterfaceVTable _noti_interface_vtable = {
" <arg type='a(v)' name='dnd_allow_exception' direction='out'/>"
" </method>"
+ " <method name='send_noti_event'>"
+ " <arg type='v' name='noti' direction='in'/>"
+ " <arg type='i' name='event_type' direction='in'/>"
+ " </method>"
+
" <method name='post_toast'>"
" </method>"
" </interface>"
return service_common_register_dbus_interface(introspection_xml, _noti_interface_vtable);
}
+static void __free_event_list(gpointer data)
+{
+ event_sender_info_s *info = (event_sender_info_s *)data;
+
+ if (info) {
+ if (info->busname)
+ free(info->busname);
+ free(info);
+ }
+}
+
+static void __free_event_hash(gpointer data)
+{
+ GList *event_list = (GList *)data;
+ if (event_list)
+ g_list_free_full(event_list, __free_event_list);
+}
+
+static gint __priv_id_compare(gconstpointer a, gconstpointer b)
+{
+ event_sender_info_s *info = NULL;
+
+ if (!a)
+ return -1;
+
+ info = (event_sender_info_s *)a;
+
+ if (info->priv_id == GPOINTER_TO_UINT(b))
+ return 0;
+
+ return 1;
+}
+
/* add noti */
static int _add_noti(GVariant **reply_body, notification_h noti, GList *monitoring_list)
{
print_noti(noti);
ret = notification_noti_insert(noti);
- notification_get_id(noti, NULL, &priv_id);
- DbgPrint("priv_id: [%d]", priv_id);
-
if (ret != NOTIFICATION_ERROR_NONE) {
ErrPrint("failed to update a notification:%d\n", ret);
return ret;
}
+ ret = notification_get_id(noti, NULL, &priv_id);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ErrPrint("failed to gets priv_id:%d\n", ret);
+ return ret;
+ }
+
body = notification_ipc_make_gvariant_from_noti(noti, true);
if (body == NULL) {
ErrPrint("cannot make gvariant to noti");
return NOTIFICATION_ERROR_OUT_OF_MEMORY;
}
+
ret = send_notify(body, "add_noti_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
g_variant_unref(body);
return ret;
}
-int notification_add_noti(GVariant *parameters, GVariant **reply_body, uid_t uid)
+static int __add_sender_info(int priv_id, const char *busname, uid_t uid)
+{
+ GList *event_list = NULL;
+ GList *find_list = NULL;
+ event_sender_info_s *sender_info;
+
+ if (__event_sender_hash == NULL)
+ __event_sender_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __free_event_hash);
+
+ event_list = g_hash_table_lookup(__event_sender_hash, GUINT_TO_POINTER(uid));
+
+ sender_info = (event_sender_info_s *)malloc(sizeof(event_sender_info_s));
+ if (sender_info == NULL) {
+ DbgPrint("malloc failed");
+ return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+
+ sender_info->priv_id = priv_id;
+ sender_info->busname = strdup(busname);
+
+ if (event_list == NULL) {
+ event_list = g_list_append(event_list, sender_info);
+ g_hash_table_insert(__event_sender_hash, GUINT_TO_POINTER(uid), event_list);
+ } else {
+ event_list = g_list_first(event_list);
+ find_list = g_list_find_custom(event_list, GUINT_TO_POINTER(priv_id),
+ (GCompareFunc)__priv_id_compare);
+ if (find_list == NULL) {
+ event_list = g_list_append(event_list, sender_info);
+ } else {
+ if (sender_info) {
+ if (sender_info->busname)
+ free(sender_info->busname);
+ free(sender_info);
+ }
+ }
+ }
+
+ return NOTIFICATION_ERROR_NONE;
+}
+
+int notification_add_noti(GVariant *parameters, GVariant **reply_body, const char *sender, uid_t uid)
{
int ret;
+ int priv_id;
+ bool event_flag;
notification_h noti;
GVariant *body = NULL;
GList *monitoring_list = NULL;
else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
ret = _update_noti(reply_body, noti, monitoring_list);
+ ret = notification_get_event_flag(noti, &event_flag);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
+
+ if (event_flag == true) {
+ ret = notification_get_id(noti, NULL, &priv_id);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
+
+ __add_sender_info(priv_id, sender, noti_uid);
+ }
notification_free(noti);
} else {
ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
return ret;
}
+static int __delete_sender_info(int priv_id, uid_t uid)
+{
+ int ret = NOTIFICATION_ERROR_NONE;
+ event_sender_info_s *info;
+ GList *event_list = NULL;
+ GList *delete_list = NULL;
+ GVariant *body = NULL;
+
+ if (__event_sender_hash == NULL)
+ return NOTIFICATION_ERROR_NONE;
+
+ event_list = g_hash_table_lookup(__event_sender_hash, GUINT_TO_POINTER(uid));
+
+ if (event_list != NULL) {
+ event_list = g_list_first(event_list);
+ delete_list = g_list_find_custom(event_list, GUINT_TO_POINTER(priv_id),
+ (GCompareFunc)__priv_id_compare);
+ if (delete_list != NULL) {
+ info = g_list_nth_data(delete_list, 0);
+ body = g_variant_new("(i)", priv_id);
+ ret = send_event_notify_by_busname(body, "delete_noti", info->busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
+ g_variant_unref(body);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ErrPrint("failed to send event notify:%d\n", ret);
+ return ret;
+ }
+ event_list = g_list_remove(g_list_first(event_list), info);
+ if (info->busname)
+ free(info->busname);
+ if (info)
+ free(info);
+ }
+ }
+
+ return ret;
+}
+
/* del_noti_single */
int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, uid_t uid)
{
ErrPrint("failed to send notify:%d\n", ret);
return ret;
}
+
+ ret = __delete_sender_info(priv_id, uid);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
}
*reply_body = g_variant_new("(i)", priv_id);
return ret;
ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted, param_uid);
+
DbgPrint("ret: [%d] num_deleted: [%d]\n", ret, num_deleted);
if (ret != NOTIFICATION_ERROR_NONE) {
deleted_noti_list = g_variant_new("(a(i)i)", builder, param_uid);
monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
ret = send_notify(deleted_noti_list, "delete_multiple_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
-
g_variant_builder_unref(builder);
g_variant_unref(deleted_noti_list);
- free(list_deleted);
-
if (ret != NOTIFICATION_ERROR_NONE) {
ErrPrint("failed to send notify:%d\n", ret);
return ret;
}
+
+ for (i = 0; i < num_deleted; i++) {
+ ret = __delete_sender_info(*(list_deleted + i), param_uid);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
+ }
+
+ free(list_deleted);
}
*reply_body = g_variant_new("(i)", num_deleted);
return ret;
}
+static char *__find_busname_by_priv_id(int priv_id, uid_t uid)
+{
+ char *busname = NULL;
+ event_sender_info_s *event_info;
+ GList *event_list;
+ GList *find_list;
+
+ if (__event_sender_hash == NULL)
+ return NULL;
+
+ event_list = g_hash_table_lookup(__event_sender_hash, GUINT_TO_POINTER(uid));
+ if (event_list == NULL)
+ return NULL;
+
+ event_list = g_list_first(event_list);
+ find_list = g_list_find_custom(event_list, GUINT_TO_POINTER(priv_id),
+ (GCompareFunc)__priv_id_compare);
+
+ if (find_list) {
+ event_info = g_list_nth_data(find_list, 0);
+ busname = strdup(event_info->busname);
+ } else {
+ return NULL;
+ }
+
+ return busname;
+}
+
+int notification_send_noti_event(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int event_type;
+ int priv_id;
+ char *busname = NULL;
+ GVariant *coupled_body = NULL;
+ GVariant *body = NULL;
+ notification_h noti;
+ uid_t noti_uid;
+
+ noti = notification_create(NOTIFICATION_TYPE_NOTI);
+
+ if (noti != NULL) {
+ g_variant_get(parameters, "(vi)", &coupled_body, &event_type);
+ g_variant_get(coupled_body, "(v)", &body);
+
+ ret = notification_ipc_make_noti_from_gvariant(noti, body);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ErrPrint("failed to make a notification from gvariant");
+ return ret;
+ }
+
+ g_variant_unref(coupled_body);
+ g_variant_unref(body);
+
+ ret = notification_get_id(noti, NULL, &priv_id);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
+
+ ret = notification_get_uid(noti, ¬i_uid);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ return ret;
+
+ busname = __find_busname_by_priv_id(priv_id, noti_uid);
+ if (busname == NULL)
+ return NOTIFICATION_ERROR_INVALID_PARAMETER;
+
+ ret = send_event_notify_by_busname(parameters, "send_event", busname, PROVIDER_NOTI_EVENT_INTERFACE_NAME);
+ notification_free(noti);
+ free(busname);
+ } else {
+ ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ ErrPrint("cannot make reply body");
+ return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+ return ret;
+}
+
static void _notification_data_init(void)
{
int property = 0;
notification_get_type(noti, ¬i_type);
if (noti_type == NOTIFICATION_TYPE_ONGOING
- || property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
+ || property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
notification_noti_delete_by_priv_id(noti_pkgname, priv_id);
}
}