Fix wrong logic that handle busname for emit signal 00/102400/4 accepted/tizen/3.0/common/20161207.194758 accepted/tizen/3.0/ivi/20161207.012957 accepted/tizen/3.0/mobile/20161207.012907 accepted/tizen/3.0/tv/20161207.012921 accepted/tizen/3.0/wearable/20161207.012937 submit/tizen_3.0/20161206.101358
authorseungha.son <seungha.son@samsung.com>
Mon, 5 Dec 2016 13:47:24 +0000 (22:47 +0900)
committerseungha.son <seungha.son@samsung.com>
Tue, 6 Dec 2016 09:41:20 +0000 (18:41 +0900)
 - Remove connection data from g_list data structure.
 - Remove connection data when vanished connection.
 - If data-provider-master lose connection busname,
   it is critical issue when emit signal to registered process
   It terminates the logic without sending a signal to
   another subscribing process.

Signed-off-by: seungha.son <seungha.son@samsung.com>
Change-Id: I118802628028875151bd21ffc85772e30ad7d135

include/service_common.h
include/shortcut_service.h
src/badge_service.c
src/notification_service.c
src/service_common.c
src/shortcut_service.c

index eda0585..a44d8c1 100755 (executable)
@@ -49,13 +49,15 @@ typedef struct monitoring_info {
 } monitoring_info_s;
 
 void print_noti(notification_h noti);
-int send_notify(GVariant *body, char *cmd, GList *monitoring_app_list, char *interface_name);
+int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash, char *interface_name, uid_t uid);
 int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname, char *interface_name);
 int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
        GBusNameAppearedCallback name_appeared_handler,
        GBusNameVanishedCallback name_vanished_handler,
        GHashTable **monitoring_hash,
        uid_t uid);
+int service_unregister(GVariant *parameters, GVariant **reply_body, const gchar *sender, GHashTable **monitoring_hash, uid_t uid);
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid);
 GDBusConnection *service_common_get_connection();
 int service_common_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable);
 uid_t get_sender_uid(const char *sender_name);
index fd9c6f4..c42295e 100755 (executable)
@@ -19,9 +19,9 @@
 extern int shortcut_service_init(void);
 extern int shortcut_service_fini(void);
 
-int shortcut_add(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid);
-int shortcut_add_widget(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid);
-int shortcut_remove(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid);
+int shortcut_add(GVariant *parameters, GVariant **reply_body, uid_t uid);
+int shortcut_add_widget(GVariant *parameters, GVariant **reply_body, uid_t uid);
+int shortcut_remove(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int shortcut_register_dbus_interface();
 int shortcut_get_shortcut_service_list(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int shortcut_check_privilege(void);
index 08e63bc..2289a66 100755 (executable)
@@ -49,6 +49,11 @@ static void _on_name_vanished(GDBusConnection *connection,
        if (info) {
                DbgPrint("name vanished uid : %d", info->uid);
                g_bus_unwatch_name(info->watcher_id);
+               delete_monitoring_list(&_monitoring_hash, name, info->uid);
+
+               if (info->bus_name)
+                       free(info->bus_name);
+               free(info);
        }
 }
 
@@ -118,15 +123,18 @@ int badge_register_dbus_interface()
                        "        <method name='badge_service_register'>"
                        "          <arg type='i' name='uid' direction='in'/>"
                        "        </method>"
+
                        "        <method name='get_badge_existing'>"
                        "          <arg type='s' name='pkgname' direction='in'/>"
                        "          <arg type='i' name='uid' direction='in'/>"
                        "          <arg type='i' name='exist' direction='out'/>"
                        "        </method>"
+
                        "        <method name='get_list'>"
                        "          <arg type='i' name='uid' direction='in'/>"
                        "          <arg type='a(v)' name='badge_list' direction='out'/>"
                        "        </method>"
+
                        "        <method name='insert_badge'>"
                        "          <arg type='s' name='pkgname' direction='in'/>"
                        "          <arg type='s' name='writable_pkg' direction='in'/>"
@@ -302,7 +310,6 @@ int badge_insert(GVariant *parameters, GVariant **reply_body, uid_t uid)
        char *writable_pkg = NULL;
        char *caller = NULL;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
        uid_t param_uid;
        int allow_to_display = 0;
 
@@ -335,8 +342,7 @@ int badge_insert(GVariant *parameters, GVariant **reply_body, uid_t uid)
                        return BADGE_ERROR_OUT_OF_MEMORY;
                }
 
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-               ret = send_notify(body, "insert_badge_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+               ret = send_notify(body, "insert_badge_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
                g_variant_unref(body);
 
                if (ret != BADGE_ERROR_NONE) {
@@ -361,7 +367,6 @@ int badge_delete(GVariant *parameters, GVariant **reply_body, uid_t uid)
        char *pkgname = NULL;
        char *caller = NULL;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
        uid_t param_uid;
 
        g_variant_get(parameters, "(&s&si)", &pkgname, &caller, &param_uid);
@@ -387,8 +392,7 @@ int badge_delete(GVariant *parameters, GVariant **reply_body, uid_t uid)
                return BADGE_ERROR_OUT_OF_MEMORY;
        }
 
-       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-       ret = send_notify(body, "delete_badge_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+       ret = send_notify(body, "delete_badge_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
        g_variant_unref(body);
 
        if (ret != BADGE_ERROR_NONE) {
@@ -412,7 +416,6 @@ int badge_set_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid
        char *caller = NULL;
        unsigned int count = 0;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
        uid_t param_uid;
        int allow_to_display = 0;
 
@@ -445,8 +448,7 @@ int badge_set_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid
                        return BADGE_ERROR_OUT_OF_MEMORY;
                }
 
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-               ret = send_notify(body, "set_badge_count_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+               ret = send_notify(body, "set_badge_count_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
                g_variant_unref(body);
 
                if (ret != BADGE_ERROR_NONE) {
@@ -505,7 +507,6 @@ int badge_set_display_option(GVariant *parameters, GVariant **reply_body, uid_t
        char *caller = NULL;
        unsigned int is_display = 0;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
        uid_t param_uid;
        int allow_to_display = 0;
 
@@ -540,8 +541,7 @@ int badge_set_display_option(GVariant *parameters, GVariant **reply_body, uid_t
                        return BADGE_ERROR_OUT_OF_MEMORY;
                }
 
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-               ret = send_notify(body, "set_disp_option_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+               ret = send_notify(body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
                g_variant_unref(body);
 
                if (ret != BADGE_ERROR_NONE) {
@@ -624,7 +624,6 @@ static int __badge_emit_fake_signal(char *appid, unsigned int disp_option, uid_t
 {
        int ret;
        GVariant *fake_body = NULL;
-       GList *monitoring_list = NULL;
 
        fake_body = g_variant_new("(sii)", appid, disp_option, uid);
        if (fake_body == NULL) {
@@ -632,8 +631,7 @@ static int __badge_emit_fake_signal(char *appid, unsigned int disp_option, uid_t
                return BADGE_ERROR_OUT_OF_MEMORY;
        }
 
-       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(uid));
-       ret = send_notify(fake_body, "set_disp_option_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+       ret = send_notify(fake_body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, uid);
        g_variant_unref(fake_body);
        if (ret != BADGE_ERROR_NONE)
                ErrPrint("failed to send notify:%d\n", ret);
@@ -735,7 +733,6 @@ int badge_init_display(GVariant *parameters, GVariant **reply_body, uid_t uid)
        int allow_to_display;
        GList *badge_list = NULL;
        GList *iter_list  = NULL;
-       GList *monitoring_list = NULL;
        GVariant *body = NULL;
        badge_info_s *badge;
        uid_t param_uid;
@@ -769,10 +766,8 @@ int badge_init_display(GVariant *parameters, GVariant **reply_body, uid_t uid)
                }
 
                if (disp_option && allow_to_display) {
-                       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-
                        body = g_variant_new("(sii)", badge->pkg, disp_option, param_uid);
-                       ret = send_notify(body, "set_disp_option_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
+                       ret = send_notify(body, "set_disp_option_notify", &_monitoring_hash, PROVIDER_BADGE_INTERFACE_NAME, param_uid);
                        if (ret != BADGE_ERROR_NONE) {
                                ErrPrint("failed to get allow_to_display");
                                continue;
@@ -801,7 +796,7 @@ HAPI int badge_service_init(void)
 {
        int result;
 
-       _monitoring_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_monitoring_list);
+       _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
        result = badge_db_init();
        if (result != BADGE_ERROR_NONE) {
                ErrPrint("badge db init fail %d", result);
index 4d4b9ee..7a42e35 100755 (executable)
@@ -45,7 +45,7 @@
 typedef struct _dnd_alarm_id dnd_alarm_id_s;
 
 static GHashTable *_monitoring_hash;
-static int _update_noti(GVariant **reply_body, notification_h noti, GList *monitoring_list);
+static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
 
 static GList *_dnd_alarm_id_list;
 
@@ -75,7 +75,9 @@ static void _on_name_appeared(GDBusConnection *connection,
                const gchar     *name_owner,
                gpointer         user_data)
 {
-       DbgPrint("name appeared : %s", name);
+       monitoring_info_s *info = (monitoring_info_s *)user_data;
+
+       DbgPrint("name appeared name : %s, uid : %d", name, info->uid);
 }
 
 static void _on_name_vanished(GDBusConnection *connection,
@@ -87,6 +89,11 @@ static void _on_name_vanished(GDBusConnection *connection,
        if (info) {
                DbgPrint("name vanished uid : %d", info->uid);
                g_bus_unwatch_name(info->watcher_id);
+               delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
+
+               if (info->bus_name)
+                       free(info->bus_name);
+               free(info);
        }
 }
 
@@ -363,7 +370,7 @@ static gint __priv_id_compare(gconstpointer a, gconstpointer b)
 }
 
 /* add noti */
-static int _add_noti(GVariant **reply_body, notification_h noti, GList *monitoring_list)
+static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
 {
        int ret;
        int priv_id = NOTIFICATION_PRIV_ID_NONE;
@@ -388,7 +395,7 @@ static int _add_noti(GVariant **reply_body, notification_h noti, GList *monitori
                return NOTIFICATION_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = send_notify(body, "add_noti_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+       ret = send_notify(body, "add_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
        g_variant_unref(body);
 
        if (ret != NOTIFICATION_ERROR_NONE) {
@@ -515,7 +522,6 @@ int notification_add_noti(GVariant *parameters, GVariant **reply_body, const cha
        bool event_flag;
        notification_h noti;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
        uid_t noti_uid = 0;
 
        noti = notification_create(NOTIFICATION_TYPE_NOTI);
@@ -528,13 +534,11 @@ int notification_add_noti(GVariant *parameters, GVariant **reply_body, const cha
                if (ret != NOTIFICATION_ERROR_NONE)
                        return ret;
 
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(noti_uid));
-
                ret = notification_noti_check_tag(noti);
                if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID)
-                       ret = _add_noti(reply_body, noti, monitoring_list);
+                       ret = _add_noti(reply_body, noti, noti_uid);
                else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
-                       ret = _update_noti(reply_body, noti, monitoring_list);
+                       ret = _update_noti(reply_body, noti, noti_uid);
 
                ret = notification_get_event_flag(noti, &event_flag);
                if (ret != NOTIFICATION_ERROR_NONE)
@@ -557,7 +561,7 @@ int notification_add_noti(GVariant *parameters, GVariant **reply_body, const cha
 }
 
 /* update noti */
-static int _update_noti(GVariant **reply_body, notification_h noti, GList *monitoring_list)
+static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid)
 {
        int ret;
        GVariant *body = NULL;
@@ -577,7 +581,7 @@ static int _update_noti(GVariant **reply_body, notification_h noti, GList *monit
                return NOTIFICATION_ERROR_IO_ERROR;
        }
 
-       ret = send_notify(body, "update_noti_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+       ret = send_notify(body, "update_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
        g_variant_unref(body);
 
        if (ret != NOTIFICATION_ERROR_NONE) {
@@ -600,7 +604,6 @@ int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t
        int ret;
        GVariant *body = NULL;
        uid_t noti_uid;
-       GList *monitoring_list = NULL;
 
        noti = notification_create(NOTIFICATION_TYPE_NOTI);
        if (noti != NULL) {
@@ -612,9 +615,8 @@ int notification_update_noti(GVariant *parameters, GVariant **reply_body, uid_t
                if (ret != NOTIFICATION_ERROR_NONE)
                        return ret;
 
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(noti_uid));
                if (ret == NOTIFICATION_ERROR_NONE)
-                       ret = _update_noti(reply_body, noti, monitoring_list);
+                       ret = _update_noti(reply_body, noti, noti_uid);
 
                notification_free(noti);
        } else {
@@ -923,15 +925,13 @@ int notification_refresh_noti(GVariant *parameters, GVariant **reply_body, uid_t
 {
        int ret;
        uid_t param_uid;
-       GList *monitoring_list = NULL;
 
        g_variant_get(parameters, "(i)", &param_uid);
        ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
        if (ret != NOTIFICATION_ERROR_NONE)
                return ret;
 
-       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-       ret = send_notify(parameters, "refresh_noti_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+       ret = send_notify(parameters, "refresh_noti_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
        if (ret != NOTIFICATION_ERROR_NONE) {
                ErrPrint("failed to send notify:%d\n", ret);
                return ret;
@@ -991,7 +991,6 @@ int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, ui
        char *pkgname = NULL;
        GVariant *body = NULL;
        uid_t param_uid;
-       GList *monitoring_list = NULL;
 
        g_variant_get(parameters, "(&sii)", &pkgname, &priv_id, &param_uid);
        ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
@@ -1010,8 +1009,7 @@ int notification_del_noti_single(GVariant *parameters, GVariant **reply_body, ui
                        ErrPrint("cannot make gvariant to noti");
                        return NOTIFICATION_ERROR_OUT_OF_MEMORY;
                }
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
-               ret = send_notify(body, "delete_single_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+               ret = send_notify(body, "delete_single_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
                g_variant_unref(body);
                if (ret != NOTIFICATION_ERROR_NONE) {
                        ErrPrint("failed to send notify:%d\n", ret);
@@ -1044,7 +1042,6 @@ int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body,
        GVariantBuilder *builder;
        int i;
        uid_t param_uid;
-       GList *monitoring_list = NULL;
 
        g_variant_get(parameters, "(&sii)", &pkgname, &type, &param_uid);
        DbgPrint("pkgname: [%s] type: [%d]\n", pkgname, type);
@@ -1070,8 +1067,7 @@ int notification_del_noti_multiple(GVariant *parameters, GVariant **reply_body,
                        g_variant_builder_add(builder, "(i)", *(list_deleted + i));
 
                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);
+               ret = send_notify(deleted_noti_list, "delete_multiple_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
                g_variant_builder_unref(builder);
                g_variant_unref(deleted_noti_list);
                if (ret != NOTIFICATION_ERROR_NONE) {
@@ -1185,7 +1181,6 @@ static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
        bool dnd_id_found = false;
        GVariant *body = NULL;
        GList *dnd_found_list = NULL;
-       GList *monitoring_list = NULL;
        dnd_alarm_id_s *dnd_id_data = NULL;
        uid_t uid;
 
@@ -1222,8 +1217,7 @@ static int _dnd_schedule_alarm_cb(alarm_id_t alarm_id, void *data)
 
        body = g_variant_new("(ii)", do_not_disturb, uid);
 
-       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(uid));
-       ret = send_notify(body, "change_dnd_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+       ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, uid);
        g_variant_unref(body);
        if (ret != NOTIFICATION_ERROR_NONE) {
                ErrPrint("failed to send notify:%d\n", ret);
@@ -1452,7 +1446,6 @@ int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_
        int lock_screen_level = 0;
        uid_t param_uid;
        GVariant *body = NULL;
-       GList *monitoring_list = NULL;
 
        g_variant_get(parameters, "(iiiiiiiiii)",
                                &do_not_disturb,
@@ -1496,8 +1489,7 @@ int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_
 
        if (pre_do_not_disturb != do_not_disturb) {
                body = g_variant_new("(ii)", do_not_disturb, param_uid);
-               monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(uid));
-               ret = send_notify(body, "change_dnd_notify", monitoring_list, PROVIDER_NOTI_INTERFACE_NAME);
+               ret = send_notify(body, "change_dnd_notify", &_monitoring_hash, PROVIDER_NOTI_INTERFACE_NAME, param_uid);
                g_variant_unref(body);
        }
 
@@ -1921,7 +1913,7 @@ HAPI int notification_service_init(void)
        int count = 0;
        uid_t *uids = NULL;
 
-       _monitoring_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_monitoring_list);
+       _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
        ret = notification_db_init();
        if (ret != NOTIFICATION_ERROR_NONE) {
                ErrPrint("notification db init fail %d", ret);
index 2f2f2f7..14b1d4a 100755 (executable)
@@ -62,22 +62,6 @@ void print_noti(notification_h noti)
        DbgPrint("provider print_noti  vibration_path  = %s %d", vibration_path, type);
 }
 
-static void _free_monitoring_info(gpointer data)
-{
-       monitoring_info_s *info = (monitoring_info_s *)data;
-       if (info) {
-               free(info->bus_name);
-               g_bus_unwatch_name(info->watcher_id);
-               free(info);
-       }
-}
-
-void free_monitoring_list(gpointer data)
-{
-       GList *monitoring_list = (GList *)data;
-       g_list_free_full(monitoring_list, _free_monitoring_info);
-}
-
 uid_t get_sender_uid(const char *sender_name)
 {
        GDBusMessage *msg = NULL;
@@ -156,17 +140,62 @@ out:
        return pid;
 }
 
-int send_notify(GVariant *body, char *cmd, GList *monitoring_app_list, char *interface_name)
+static bool _is_existed_busname(const char *sender_name)
 {
+       GDBusMessage *msg = NULL;
+       GDBusMessage *reply = NULL;
        GError *err = NULL;
+       GVariant *body;
+       bool is_existed = false;
+
+       msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
+                       "org.freedesktop.DBus", "NameHasOwner");
+       if (!msg) {
+               LOGE("Can't allocate new method call");
+               goto out;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
+
+       if (!reply) {
+               if (err != NULL) {
+                       LOGE("Failed to get uid [%s]", err->message);
+                       g_error_free(err);
+               }
+               goto out;
+       }
+
+       body = g_dbus_message_get_body(reply);
+       g_variant_get(body, "(b)", &is_existed);
+
+out:
+       if (msg)
+               g_object_unref(msg);
+       if (reply)
+               g_object_unref(reply);
+
+       return is_existed;
+}
+
+int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash, char *interface_name, uid_t uid)
+{
+       GError *err = NULL;
+       GList *monitoring_list = NULL;
        GList *target_list;
        char *target_bus_name;
        int monitoring_count = 0;
+       bool is_existed = false;
+
+       DbgPrint("send_notify uid : %d", uid);
 
-       target_list = g_list_first(monitoring_app_list);
-       for (; target_list != NULL; target_list = target_list->next) {
+       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+       target_list = g_list_first(monitoring_list);
+       for (; target_list != NULL; ) {
                err = NULL;
                target_bus_name = target_list->data;
+               target_list = target_list->next;
 
                if (g_variant_is_floating(body))
                        g_variant_ref(body);
@@ -186,7 +215,10 @@ int send_notify(GVariant *body, char *cmd, GList *monitoring_app_list, char *int
                                                err->message);
                                g_error_free(err);
                        }
-                       return SERVICE_COMMON_ERROR_IO_ERROR;
+                       is_existed = _is_existed_busname(target_bus_name);
+                       if (is_existed == false)
+                               delete_monitoring_list(monitoring_hash, target_bus_name, uid);
+                       ErrPrint("failed to emit signal: %s", target_bus_name);
                }
                monitoring_count++;
                DbgPrint("signal send done: %s", target_bus_name);
@@ -263,6 +295,7 @@ int service_register(GVariant *parameters, GVariant **reply_body, const gchar *s
                }
 
                m_info->bus_name = strdup(bus_name);
+               m_info->uid = request_uid;
                m_info->watcher_id = g_bus_watch_name_on_connection(
                                _gdbus_conn,
                                bus_name,
@@ -283,10 +316,8 @@ int service_register(GVariant *parameters, GVariant **reply_body, const gchar *s
                monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
                DbgPrint("service_register : register success sender is %s , length : %d",
                                sender, g_list_length(monitoring_list));
-               if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL) {
+               if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL)
                        g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
-               }
-
        } else {
                ErrPrint("service_register : register sender %s already exist", sender);
        }
@@ -302,6 +333,39 @@ int service_register(GVariant *parameters, GVariant **reply_body, const gchar *s
        return SERVICE_COMMON_ERROR_NONE;
 }
 
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid)
+{
+       GList *monitoring_list = NULL;
+       GList *del_list = NULL;
+       char *bus_name;
+
+       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+       if (monitoring_list == NULL) {
+               ErrPrint("Failed g_hash_table_lookup uid : %d", uid);
+               return SERVICE_COMMON_ERROR_IO_ERROR;
+       }
+
+       monitoring_list = g_list_first(monitoring_list);
+       del_list = g_list_find_custom(monitoring_list, sender,
+                       (GCompareFunc)_monitoring_app_list_compare_cb);
+
+       if (del_list) {
+               DbgPrint("Find delete list - uid : %d , sender : %s", uid, sender);
+               bus_name = g_list_nth_data(del_list, 0);
+               if (bus_name)
+                       free(bus_name);
+               monitoring_list = g_list_delete_link(monitoring_list, del_list);
+
+               if (monitoring_list == NULL) {
+                       g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
+               } else {
+                       monitoring_list = g_list_first(monitoring_list);
+                       g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
+               }
+       }
+       return SERVICE_COMMON_ERROR_NONE;
+}
+
 static int _dbus_init(void)
 {
        GError *error = NULL;
index a02b609..9410008 100755 (executable)
@@ -41,6 +41,11 @@ static void _on_name_vanished(GDBusConnection *connection,
        if (info) {
                DbgPrint("name vanished uid : %d", info->uid);
                g_bus_unwatch_name(info->watcher_id);
+               delete_monitoring_list(&_monitoring_hash, name, info->uid);
+
+               if (info->bus_name)
+                       free(info->bus_name);
+               free(info);
        }
 }
 
@@ -55,18 +60,16 @@ static void _shortcut_dbus_method_call_handler(GDBusConnection *conn,
        GVariant *reply_body = NULL;
        int ret = SHORTCUT_ERROR_NOT_SUPPORTED;
        uid_t uid = get_sender_uid(sender);
-       GList *monitoring_list = NULL;
 
-       monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(uid));
        if (g_strcmp0(method_name, "shortcut_service_register") == 0)
                ret = service_register(parameters, &reply_body, sender,
                 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
        else if (g_strcmp0(method_name, "add_shortcut") == 0)
-               ret = shortcut_add(parameters, &reply_body, monitoring_list, uid);
+               ret = shortcut_add(parameters, &reply_body, uid);
        else if (g_strcmp0(method_name, "add_shortcut_widget") == 0)
-               ret = shortcut_add_widget(parameters, &reply_body, monitoring_list, uid);
+               ret = shortcut_add_widget(parameters, &reply_body, uid);
        else if (g_strcmp0(method_name, "remove_shortcut") == 0)
-               ret = shortcut_remove(parameters, &reply_body, monitoring_list, uid);
+               ret = shortcut_remove(parameters, &reply_body, uid);
        else if (g_strcmp0(method_name, "get_list") == 0)
                ret = shortcut_get_shortcut_service_list(parameters, &reply_body, uid);
        else if (g_strcmp0(method_name, "check_privilege") == 0)
@@ -206,11 +209,11 @@ int shortcut_get_shortcut_service_list(GVariant *parameters, GVariant **reply_bo
 }
 
 /* add_shortcut */
-int shortcut_add(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid)
+int shortcut_add(GVariant *parameters, GVariant **reply_body, uid_t uid)
 {
        int ret = SERVICE_COMMON_ERROR_NONE;
 
-       ret = send_notify(parameters, "add_shortcut_notify", monitoring_list, PROVIDER_SHORTCUT_INTERFACE_NAME);
+       ret = send_notify(parameters, "add_shortcut_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
        if (ret != SERVICE_COMMON_ERROR_NONE) {
                ErrPrint("failed to send notify:%d\n", ret);
                return ret;
@@ -226,11 +229,11 @@ int shortcut_add(GVariant *parameters, GVariant **reply_body, GList *monitoring_
 }
 
 /* add_shortcut_widget */
-int shortcut_add_widget(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid)
+int shortcut_add_widget(GVariant *parameters, GVariant **reply_body, uid_t uid)
 {
        int ret = SERVICE_COMMON_ERROR_NONE;
 
-       ret = send_notify(parameters, "add_shortcut_widget_notify", monitoring_list, PROVIDER_SHORTCUT_INTERFACE_NAME);
+       ret = send_notify(parameters, "add_shortcut_widget_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
        if (ret != SERVICE_COMMON_ERROR_NONE) {
                ErrPrint("failed to send notify:%d\n", ret);
                return ret;
@@ -246,11 +249,11 @@ int shortcut_add_widget(GVariant *parameters, GVariant **reply_body, GList *moni
 }
 
 /* remove_shortcut */
-int shortcut_remove(GVariant *parameters, GVariant **reply_body, GList *monitoring_list, uid_t uid)
+int shortcut_remove(GVariant *parameters, GVariant **reply_body, uid_t uid)
 {
        int ret = SERVICE_COMMON_ERROR_NONE;
 
-       ret = send_notify(parameters, "remove_shortcut_notify", monitoring_list, PROVIDER_SHORTCUT_INTERFACE_NAME);
+       ret = send_notify(parameters, "remove_shortcut_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
        if (ret != SERVICE_COMMON_ERROR_NONE) {
                ErrPrint("failed to send notify:%d\n", ret);
                return ret;
@@ -279,11 +282,10 @@ HAPI int shortcut_service_init(void)
 {
        DbgPrint("Successfully initiated\n");
        int result;
-       _monitoring_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_monitoring_list);
+       _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
        result = shortcut_register_dbus_interface();
-       if (result != SERVICE_COMMON_ERROR_NONE) {
+       if (result != SERVICE_COMMON_ERROR_NONE)
                ErrPrint("shortcut register dbus fail %d", result);
-       }
        return result;
 }