From 007572a3c25aa3c4dda6e31acb1750cc3eb84dff Mon Sep 17 00:00:00 2001 From: "seungha.son" Date: Mon, 27 Jun 2016 11:46:59 +0900 Subject: [PATCH] Modify notification register changed callback - register changed callback for uid - changed callback invoked for uid - unregister changed callback for uid Signed-off-by: seungha.son Change-Id: I47c8f5975ffe692aced454c244b4f8f30c02c1bf --- include/notification_internal.h | 15 ++- include/notification_private.h | 2 +- src/notification_internal.c | 249 +++++++++++++++++++--------------------- src/notification_ipc.c | 39 ++++--- 4 files changed, 151 insertions(+), 154 deletions(-) diff --git a/include/notification_internal.h b/include/notification_internal.h index dcfd983..5db7d7f 100644 --- a/include/notification_internal.h +++ b/include/notification_internal.h @@ -58,11 +58,6 @@ int notification_del_deferred_task( void (*deferred_task_cb)(void *data)); -int -notification_resister_changed_cb_for_uid( - void (*changed_cb)(void *data, notification_type_e type), - void *user_data, uid_t uid); - /** * @brief This function will be removed. * @see notification_unresister_changed_cb() @@ -72,6 +67,10 @@ notification_resister_changed_cb( void (*changed_cb)(void *data, notification_type_e type), void *user_data); +int +notification_resister_changed_cb_for_uid( + void (*changed_cb)(void *data, notification_type_e type), + void *user_data, uid_t uid); /** * @brief This function will be removed. * @see notification_resister_changed_cb() @@ -79,6 +78,9 @@ notification_resister_changed_cb( int notification_unresister_changed_cb( void (*changed_cb)(void *data, notification_type_e type)); +int +notification_unresister_changed_cb_for_uid( + void (*changed_cb)(void *data, notification_type_e type), uid_t uid); /** * @brief Updates the progress of the inserted notification. This only works for the ongoing notification (NOTIFICATION_TYPE_ONGOING). @@ -719,6 +721,9 @@ int notification_register_detailed_changed_cb_for_uid( 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); +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, uid_t uid); /** * @brief This function translate localized texts diff --git a/include/notification_private.h b/include/notification_private.h index 5a39fe6..9e2ad85 100644 --- a/include/notification_private.h +++ b/include/notification_private.h @@ -150,7 +150,7 @@ typedef enum notification_data_type { NOTIFICATION_DATA_TYPE_UID, } notification_data_type_e; -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); char *notification_get_pkgname_by_pid(void); diff --git a/src/notification_internal.c b/src/notification_internal.c index 36835c3..f943775 100755 --- a/src/notification_internal.c +++ b/src/notification_internal.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -41,57 +42,68 @@ #include #include -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; } } @@ -113,49 +125,40 @@ EXPORT_API int notification_del_deferred_task( 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; @@ -165,60 +168,52 @@ EXPORT_API int notification_resister_changed_cb( 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) @@ -1131,8 +1126,8 @@ EXPORT_API int notification_register_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, 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; @@ -1140,34 +1135,29 @@ EXPORT_API int notification_register_detailed_changed_cb_for_uid( 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; } @@ -1178,58 +1168,51 @@ EXPORT_API int notification_register_detailed_changed_cb( 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) { diff --git a/src/notification_ipc.c b/src/notification_ipc.c index 2267235..b437e9a 100755 --- a/src/notification_ipc.c +++ b/src/notification_ipc.c @@ -351,9 +351,11 @@ static inline bundle *_create_bundle_from_bundle_raw(bundle_raw *string) /* 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); @@ -371,9 +373,9 @@ static void _add_noti_notify(GVariant *parameters) } 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); } } @@ -385,9 +387,11 @@ static void _add_noti_notify(GVariant *parameters) /* 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) { @@ -399,8 +403,9 @@ static void _update_noti_notify(GVariant *parameters) _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); @@ -411,10 +416,13 @@ static void _update_noti_notify(GVariant *parameters) /* 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); } } @@ -426,13 +434,14 @@ static void _delete_single_notify(GVariant *parameters) 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); } } @@ -445,8 +454,9 @@ static void _delete_multiple_notify(GVariant *parameters) 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++; @@ -460,7 +470,7 @@ static void _delete_multiple_notify(GVariant *parameters) 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 */ @@ -474,7 +484,8 @@ static void _handle_noti_notify(GDBusConnection *connection, 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); @@ -489,7 +500,6 @@ static void _handle_noti_notify(GDBusConnection *connection, } /* LCOV_EXCL_STOP */ - static int _dbus_signal_init() { int id; @@ -1771,7 +1781,7 @@ static int _send_service_register(uid_t uid) 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); } @@ -1780,7 +1790,7 @@ static int _send_service_register(uid_t uid) 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); } @@ -1850,7 +1860,6 @@ int notification_ipc_monitor_init(uid_t 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); -- 2.7.4