#include <libintl.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
#include <app.h>
#include <app_control_internal.h>
#include <notification_ipc.h>
#include <notification_internal.h>
-typedef struct _notification_cb_list notification_cb_list_s;
+typedef struct _notification_cb_info notification_cb_info_s;
typedef enum __notification_cb_type {
NOTIFICATION_CB_NORMAL = 1,
NOTIFICATION_CB_DETAILED,
} _notification_cb_type_e;
-struct _notification_cb_list {
- notification_cb_list_s *prev;
- notification_cb_list_s *next;
-
+struct _notification_cb_info {
_notification_cb_type_e cb_type;
void (*changed_cb) (void *data, notification_type_e type);
void (*detailed_changed_cb) (void *data, notification_type_e type, notification_op *op_list, int num_op);
void *data;
};
-static notification_cb_list_s *g_notification_cb_list = NULL;
+static GHashTable *_noti_cb_hash = NULL;
+
+static void __free_changed_cb_info(gpointer data)
+{
+ notification_cb_info_s *noti_cb_info = (notification_cb_info_s *)data;
+ if (noti_cb_info)
+ free(noti_cb_info);
+}
+
+static void __free_changed_cb_hash(gpointer data)
+{
+ GList *changed_cb_list = (GList *)data;
+ if (changed_cb_list)
+ g_list_free_full(changed_cb_list, __free_changed_cb_info);
+}
-void notification_call_changed_cb(notification_op *op_list, int op_num)
+void notification_call_changed_cb_for_uid(notification_op *op_list, int op_num, uid_t uid)
{
- notification_cb_list_s *noti_cb_list = NULL;
notification_type_e type = 0;
+ GList *noti_cb_list = NULL;
+ notification_cb_info_s *noti_cb_info = NULL;
- if (g_notification_cb_list == NULL)
+ if (_noti_cb_hash == NULL)
return;
- noti_cb_list = g_notification_cb_list;
-
- while (noti_cb_list->prev != NULL)
- noti_cb_list = noti_cb_list->prev;
+ noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
+ if (noti_cb_list == NULL)
+ return;
if (op_list == NULL) {
NOTIFICATION_ERR("invalid data");
- return ;
+ return;
}
+ noti_cb_list = g_list_first(noti_cb_list);
notification_get_type(op_list->noti, &type);
- while (noti_cb_list != NULL) {
- if (noti_cb_list->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_list->changed_cb) {
- noti_cb_list->changed_cb(noti_cb_list->data,
- type);
+ for (; noti_cb_list != NULL; noti_cb_list = noti_cb_list->next) {
+ noti_cb_info = noti_cb_list->data;
+
+ if (noti_cb_info->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_info->changed_cb) {
+ noti_cb_info->changed_cb(noti_cb_info->data, type);
}
- if (noti_cb_list->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_list->detailed_changed_cb) {
- noti_cb_list->detailed_changed_cb(noti_cb_list->data,
+ if (noti_cb_info->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_info->detailed_changed_cb) {
+ noti_cb_info->detailed_changed_cb(noti_cb_info->data,
type, op_list, op_num);
}
-
- noti_cb_list = noti_cb_list->next;
}
}
return notification_ipc_del_deffered_task(deferred_task_cb);
}
-
EXPORT_API int notification_resister_changed_cb_for_uid(
void (*changed_cb)(void *data, notification_type_e type),
void *user_data, uid_t uid)
{
- notification_cb_list_s *noti_cb_list_new = NULL;
- notification_cb_list_s *noti_cb_list = NULL;
+ GList *noti_cb_list = NULL;
+ notification_cb_info_s *noti_cb_info_new = NULL;
if (changed_cb == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
- noti_cb_list_new =
- (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
+ if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE)
+ return NOTIFICATION_ERROR_IO_ERROR;
- if (noti_cb_list_new == NULL) {
+ if (_noti_cb_hash == NULL)
+ _noti_cb_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __free_changed_cb_hash);
+
+ noti_cb_info_new = (notification_cb_info_s *)malloc(sizeof(notification_cb_info_s));
+ if (noti_cb_info_new == NULL) {
NOTIFICATION_ERR("malloc failed");
return NOTIFICATION_ERROR_OUT_OF_MEMORY;
}
- noti_cb_list_new->next = NULL;
- noti_cb_list_new->prev = NULL;
+ noti_cb_info_new->cb_type = NOTIFICATION_CB_NORMAL;
+ noti_cb_info_new->changed_cb = changed_cb;
+ noti_cb_info_new->detailed_changed_cb = NULL;
+ noti_cb_info_new->data = user_data;
- noti_cb_list_new->cb_type = NOTIFICATION_CB_NORMAL;
- noti_cb_list_new->changed_cb = changed_cb;
- noti_cb_list_new->detailed_changed_cb = NULL;
- noti_cb_list_new->data = user_data;
+ noti_cb_list = g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
- if (g_notification_cb_list == NULL) {
- g_notification_cb_list = noti_cb_list_new;
+ if (noti_cb_list == NULL) {
+ noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
+ g_hash_table_insert(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
} else {
- noti_cb_list = g_notification_cb_list;
-
- while (noti_cb_list->next != NULL)
- noti_cb_list = noti_cb_list->next;
-
-
- noti_cb_list->next = noti_cb_list_new;
- noti_cb_list_new->prev = noti_cb_list;
- }
-
- if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE) {
- notification_unresister_changed_cb(changed_cb);
- return NOTIFICATION_ERROR_IO_ERROR;
+ noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
}
return NOTIFICATION_ERROR_NONE;
void (*changed_cb)(void *data, notification_type_e type),
void *user_data)
{
- return notification_resister_changed_cb_for_uid(
- changed_cb, user_data, getuid());
+ return notification_resister_changed_cb_for_uid(changed_cb, user_data, getuid());
}
-EXPORT_API int notification_unresister_changed_cb(
- void (*changed_cb)(void *data, notification_type_e type))
+EXPORT_API int notification_unresister_changed_cb_for_uid(
+ void (*changed_cb)(void *data, notification_type_e type), uid_t uid)
{
- notification_cb_list_s *noti_cb_list = NULL;
- notification_cb_list_s *noti_cb_list_prev = NULL;
- notification_cb_list_s *noti_cb_list_next = NULL;
-
- noti_cb_list = g_notification_cb_list;
+ notification_cb_info_s *noti_cb_info = NULL;
+ GList *noti_cb_list = NULL;
if (changed_cb == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
- if (noti_cb_list == NULL)
+ if (_noti_cb_hash == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
- while (noti_cb_list->prev != NULL)
- noti_cb_list = noti_cb_list->prev;
-
+ noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
- do {
- if (noti_cb_list->changed_cb == changed_cb) {
- noti_cb_list_prev = noti_cb_list->prev;
- noti_cb_list_next = noti_cb_list->next;
-
- if (noti_cb_list_prev == NULL)
- g_notification_cb_list = noti_cb_list_next;
- else
- noti_cb_list_prev->next = noti_cb_list_next;
+ if (noti_cb_list == NULL)
+ return NOTIFICATION_ERROR_INVALID_PARAMETER;
- if (noti_cb_list_next == NULL) {
- if (noti_cb_list_prev != NULL)
- noti_cb_list_prev->next = NULL;
+ noti_cb_list = g_list_first(noti_cb_list);
- } else {
- noti_cb_list_next->prev = noti_cb_list_prev;
- }
+ for (; noti_cb_list != NULL; noti_cb_list = noti_cb_list->next) {
+ noti_cb_info = noti_cb_list->data;
+ if (noti_cb_info->detailed_changed_cb == changed_cb) {
+ noti_cb_list = g_list_remove(g_list_first(noti_cb_list), noti_cb_info);
- free(noti_cb_list);
+ if (noti_cb_list == NULL)
+ g_hash_table_steal(_noti_cb_hash, GUINT_TO_POINTER(uid));
- if (g_notification_cb_list == NULL)
+ if (g_hash_table_size(_noti_cb_hash) == 0)
notification_ipc_monitor_fini();
return NOTIFICATION_ERROR_NONE;
}
- noti_cb_list = noti_cb_list->next;
- } while (noti_cb_list != NULL);
+ }
return NOTIFICATION_ERROR_INVALID_PARAMETER;
}
+EXPORT_API int notification_unresister_changed_cb(
+ void (*changed_cb)(void *data, notification_type_e type))
+{
+ return notification_unresister_changed_cb_for_uid(changed_cb, getuid());
+}
+
EXPORT_API int notification_update_progress(notification_h noti,
int priv_id,
double progress)
void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
void *user_data, uid_t uid)
{
- notification_cb_list_s *noti_cb_list_new = NULL;
- notification_cb_list_s *noti_cb_list = NULL;
+ GList *noti_cb_list = NULL;
+ notification_cb_info_s *noti_cb_info_new = NULL;
if (detailed_changed_cb == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE)
return NOTIFICATION_ERROR_IO_ERROR;
- noti_cb_list_new =
- (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
+ if (_noti_cb_hash == NULL)
+ _noti_cb_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __free_changed_cb_hash);
- if (noti_cb_list_new == NULL) {
+ noti_cb_info_new = (notification_cb_info_s *)malloc(sizeof(notification_cb_info_s));
+ if (noti_cb_info_new == NULL) {
NOTIFICATION_ERR("malloc failed");
return NOTIFICATION_ERROR_OUT_OF_MEMORY;
}
- noti_cb_list_new->next = NULL;
- noti_cb_list_new->prev = NULL;
+ noti_cb_info_new->cb_type = NOTIFICATION_CB_DETAILED;
+ noti_cb_info_new->changed_cb = NULL;
+ noti_cb_info_new->detailed_changed_cb = detailed_changed_cb;
+ noti_cb_info_new->data = user_data;
- noti_cb_list_new->cb_type = NOTIFICATION_CB_DETAILED;
- noti_cb_list_new->changed_cb = NULL;
- noti_cb_list_new->detailed_changed_cb = detailed_changed_cb;
- noti_cb_list_new->data = user_data;
+ noti_cb_list = g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
- if (g_notification_cb_list == NULL) {
- g_notification_cb_list = noti_cb_list_new;
+ if (noti_cb_list == NULL) {
+ noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
+ g_hash_table_insert(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
} else {
- noti_cb_list = g_notification_cb_list;
-
- while (noti_cb_list->next != NULL)
- noti_cb_list = noti_cb_list->next;
-
-
- noti_cb_list->next = noti_cb_list_new;
- noti_cb_list_new->prev = noti_cb_list;
+ noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
}
+
return NOTIFICATION_ERROR_NONE;
}
return notification_register_detailed_changed_cb_for_uid(detailed_changed_cb, user_data, getuid());
}
-EXPORT_API int notification_unregister_detailed_changed_cb(
+EXPORT_API int notification_unregister_detailed_changed_cb_for_uid(
void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
- void *user_data)
+ void *user_data, uid_t uid)
{
- notification_cb_list_s *noti_cb_list = NULL;
- notification_cb_list_s *noti_cb_list_prev = NULL;
- notification_cb_list_s *noti_cb_list_next = NULL;
-
- noti_cb_list = g_notification_cb_list;
+ notification_cb_info_s *noti_cb_info = NULL;
+ GList *noti_cb_list = NULL;
if (detailed_changed_cb == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
- if (noti_cb_list == NULL)
+ if (_noti_cb_hash == NULL)
return NOTIFICATION_ERROR_INVALID_PARAMETER;
+ noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
- while (noti_cb_list->prev != NULL)
- noti_cb_list = noti_cb_list->prev;
-
-
- do {
- if (noti_cb_list->detailed_changed_cb == detailed_changed_cb) {
- noti_cb_list_prev = noti_cb_list->prev;
- noti_cb_list_next = noti_cb_list->next;
-
- if (noti_cb_list_prev == NULL)
- g_notification_cb_list = noti_cb_list_next;
- else
- noti_cb_list_prev->next = noti_cb_list_next;
+ if (noti_cb_list == NULL)
+ return NOTIFICATION_ERROR_INVALID_PARAMETER;
- if (noti_cb_list_next == NULL) {
- if (noti_cb_list_prev != NULL)
- noti_cb_list_prev->next = NULL;
+ noti_cb_list = g_list_first(noti_cb_list);
- } else {
- noti_cb_list_next->prev = noti_cb_list_prev;
- }
+ for (; noti_cb_list != NULL; noti_cb_list = noti_cb_list->next) {
+ noti_cb_info = noti_cb_list->data;
+ if (noti_cb_info->detailed_changed_cb == detailed_changed_cb) {
+ noti_cb_list = g_list_remove(g_list_first(noti_cb_list), noti_cb_info);
- free(noti_cb_list);
+ if (noti_cb_list == NULL)
+ g_hash_table_steal(_noti_cb_hash, GUINT_TO_POINTER(uid));
- if (g_notification_cb_list == NULL)
+ if (g_hash_table_size(_noti_cb_hash) == 0)
notification_ipc_monitor_fini();
return NOTIFICATION_ERROR_NONE;
}
- noti_cb_list = noti_cb_list->next;
- } while (noti_cb_list != NULL);
+ }
return NOTIFICATION_ERROR_INVALID_PARAMETER;
}
+EXPORT_API int notification_unregister_detailed_changed_cb(
+ void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
+ void *user_data)
+{
+ return notification_unregister_detailed_changed_cb_for_uid(detailed_changed_cb, user_data, getuid());
+}
+
/* LCOV_EXCL_START */
EXPORT_API int notification_is_service_ready(void)
{
/* LCOV_EXCL_START */
static void _add_noti_notify(GVariant *parameters)
{
+ int ret;
notification_h noti;
notification_op *noti_op;
GVariant *body = NULL;
+ uid_t uid;
NOTIFICATION_DBG("add noti notify");
noti = notification_create(NOTIFICATION_TYPE_NOTI);
} else {
/* Enable changed cb */
noti_op = _ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i);
-
- if (noti_op != NULL) {
- notification_call_changed_cb(noti_op, 1);
+ ret = notification_get_uid(noti, &uid);
+ if (noti_op != NULL && ret == NOTIFICATION_ERROR_NONE) {
+ notification_call_changed_cb_for_uid(noti_op, 1, uid);
free(noti_op);
}
}
/* LCOV_EXCL_START */
static void _update_noti_notify(GVariant *parameters)
{
+ int ret;
notification_h noti;
notification_op *noti_op;
GVariant *body = NULL;
+ uid_t uid;
noti = notification_create(NOTIFICATION_TYPE_NOTI);
if (!noti) {
_print_noti(noti);
noti_op = _ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i);
- if (noti_op != NULL) {
- notification_call_changed_cb(noti_op, 1);
+ ret = notification_get_uid(noti, &uid);
+ if (noti_op != NULL && ret == NOTIFICATION_ERROR_NONE) {
+ notification_call_changed_cb_for_uid(noti_op, 1, uid);
free(noti_op);
}
g_variant_unref(body);
/* LCOV_EXCL_START */
static void _refresh_noti_notify(GVariant *parameters)
{
+ uid_t uid;
notification_op *noti_op = _ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
+ g_variant_get(parameters, "(i)", &uid);
+
if (noti_op != NULL) {
- notification_call_changed_cb(noti_op, 1);
+ notification_call_changed_cb_for_uid(noti_op, 1, uid);
free(noti_op);
}
}
int num_deleted;
int priv_id;
notification_op *noti_op;
+ uid_t uid;
/* num_deleted ?? */
- g_variant_get(parameters, "(ii)", &num_deleted, &priv_id);
+ g_variant_get(parameters, "(iii)", &num_deleted, &priv_id, &uid);
noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
if (noti_op != NULL) {
- notification_call_changed_cb(noti_op, 1);
+ notification_call_changed_cb_for_uid(noti_op, 1, uid);
free(noti_op);
}
}
int idx = 0;
notification_op *noti_op;
GVariantIter *iter;
+ uid_t uid;
- g_variant_get(parameters, "(a(i))", &iter);
+ g_variant_get(parameters, "(a(i)i)", &iter, &uid);
while (g_variant_iter_loop(iter, "(i)", &buf[idx])) {
NOTIFICATION_DBG("delete_noti_multiple priv_id : %d", buf[idx]);
idx++;
NOTIFICATION_ERR("_ipc_create_op failed");
return;
}
- notification_call_changed_cb(noti_op, idx);
+ notification_call_changed_cb_for_uid(noti_op, idx, uid);
free(noti_op);
}
/* LCOV_EXCL_STOP */
GVariant *parameters,
gpointer user_data)
{
- NOTIFICATION_DBG("signal_name: %s", signal_name);
+ NOTIFICATION_DBG("own_name : %s signal_name: %s",
+ g_dbus_connection_get_unique_name(connection), signal_name);
if (g_strcmp0(signal_name, "add_noti_notify") == 0)
_add_noti_notify(parameters);
}
/* LCOV_EXCL_STOP */
-
static int _dbus_signal_init()
{
int id;
NOTIFICATION_DBG("_send_service_register done = %s, result = %d", _bus_name, result);
noti_op = _ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
if (noti_op != NULL) {
- notification_call_changed_cb(noti_op, 1);
+ notification_call_changed_cb_for_uid(noti_op, 1, uid);
free(noti_op);
}
static int _ipc_monitor_register(uid_t uid)
{
- NOTIFICATION_ERR("register a service\n");
+ NOTIFICATION_DBG("register a service\n");
return _send_service_register(uid);
}
_on_name_vanished,
GINT_TO_POINTER((int)uid),
NULL);
-
if (provider_monitor_id == 0) {
/* LCOV_EXCL_START */
g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id);