Add gdbus permission check logic & strerror to strerror_r
[platform/core/api/notification.git] / src / notification_ipc.c
1 /*
2  *  libnotification
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <vconf.h>
27 #include <bundle_internal.h>
28
29 #include <notification_ipc.h>
30 #include <notification_db.h>
31 #include <notification_type.h>
32 #include <notification_private.h>
33 #include <notification_debug.h>
34 #include <notification_setting.h>
35 #include <notification_setting_internal.h>
36 #include <notification_internal.h>
37
38 #include <gio/gio.h>
39
40 #define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
41 #define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
42 #define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service"
43
44 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
45 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
46 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
47 #define ERR_BUFFER_SIZE         1024
48
49 static const gchar *_bus_name = NULL;
50 static GDBusConnection *_gdbus_conn = NULL;
51 static int monitor_id = 0;
52 static int provider_monitor_id = 0;
53 static int is_master_started = 0;
54
55 typedef struct _result_cb_item {
56         void (*result_cb)(int priv_id, int result, void *data);
57         void *data;
58 } result_cb_item;
59
60 typedef struct _task_list task_list;
61 struct _task_list {
62         task_list *prev;
63         task_list *next;
64
65         void (*task_cb) (void *data);
66         void *data;
67 };
68
69 static task_list *g_task_list;
70
71 static int _ipc_monitor_register(void);
72 static int _ipc_monitor_deregister(void);
73 static void _do_deffered_task(void);
74
75 static void _print_noti(notification_h noti) {
76         char *pkgname = NULL;
77         char *text = NULL;
78         char *content = NULL;
79         const char *tag = NULL;
80         notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
81
82         notification_get_pkgname(noti, &pkgname);
83         notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, &text);
84         notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content);
85         notification_get_tag(noti, &tag);
86         notification_get_vibration(noti, &vib_type, NULL);
87
88         NOTIFICATION_DBG("client print_noti  pkgname  = %s ", pkgname );
89         NOTIFICATION_DBG("client print_noti  title  = %s ", text );
90         NOTIFICATION_DBG("client print_noti  content  = %s ", content );
91         NOTIFICATION_DBG("client print_noti  tag  = %s ", tag );
92         NOTIFICATION_DBG("client print_noti  priv_id  = %d ", noti->priv_id);
93         NOTIFICATION_DBG("client print_noti  vibration_path  = %s ", noti->vibration_path);
94         NOTIFICATION_DBG("client print_noti  vibration_type  = %d ", vib_type);
95 }
96
97 static inline char *_string_get(char *string)
98 {
99         if (string == NULL)
100                 return NULL;
101
102         if (string[0] == '\0')
103                 return NULL;
104
105         return string;
106 }
107
108
109 int notification_ipc_is_master_ready(void)
110 {
111         GVariant *result;
112         GError *err = NULL;
113         gboolean name_exist;
114
115         result = g_dbus_connection_call_sync(
116                         _gdbus_conn,
117                         DBUS_SERVICE_DBUS,
118                         DBUS_PATH_DBUS,
119                         DBUS_INTERFACE_DBUS,
120                         "NameHasOwner",
121                         g_variant_new("(s)", PROVIDER_BUS_NAME),
122                         G_VARIANT_TYPE("(b)"),
123                         G_DBUS_CALL_FLAGS_NONE,
124                         -1,
125                         NULL,
126                         &err);
127
128         if (err || (result == NULL)) {
129                 if (err) {
130                 NOTIFICATION_ERR("No reply. error = %s", err->message);
131                         g_error_free(err);
132                 }
133                 is_master_started = 0;
134         } else {
135                 g_variant_get(result, "(b)", &name_exist);
136
137                 if (!name_exist) {
138                         NOTIFICATION_ERR("Name not exist %s", PROVIDER_BUS_NAME);
139                         NOTIFICATION_ERR("the master has been stopped");
140                         is_master_started = 0;
141                 } else {
142                         NOTIFICATION_DBG("the master has been started");
143                         is_master_started = 1;
144                 }
145         }
146
147         if(result)
148                 g_variant_unref(result);
149
150         return is_master_started;
151 }
152
153 /* TODO: dbus activation isn't enough ? */
154 /*
155  * store tasks when daemon stopped
156  */
157 int notification_ipc_add_deffered_task(
158                 void (*deferred_task_cb)(void *data),
159                 void *user_data)
160 {
161         task_list *list;
162         task_list *list_new;
163
164         list_new =
165             (task_list *) malloc(sizeof(task_list));
166
167         if (list_new == NULL)
168                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
169
170         list_new->next = NULL;
171         list_new->prev = NULL;
172
173         list_new->task_cb = deferred_task_cb;
174         list_new->data = user_data;
175
176         if (g_task_list == NULL) {
177                 g_task_list = list_new;
178         } else {
179                 list = g_task_list;
180
181                 while (list->next != NULL)
182                         list = list->next;
183
184                 list->next = list_new;
185                 list_new->prev = list;
186         }
187         return NOTIFICATION_ERROR_NONE;
188 }
189
190 int notification_ipc_del_deffered_task(
191                 void (*deferred_task_cb)(void *data))
192 {
193         task_list *list_del;
194         task_list *list_prev;
195         task_list *list_next;
196
197         list_del = g_task_list;
198
199         if (list_del == NULL)
200                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
201
202         while (list_del->prev != NULL)
203                 list_del = list_del->prev;
204
205         do {
206                 if (list_del->task_cb == deferred_task_cb) {
207                         list_prev = list_del->prev;
208                         list_next = list_del->next;
209
210                         if (list_prev == NULL)
211                                 g_task_list = list_next;
212                         else
213                                 list_prev->next = list_next;
214
215                         if (list_next == NULL) {
216                                 if (list_prev != NULL)
217                                         list_prev->next = NULL;
218                         } else {
219                                 list_next->prev = list_prev;
220                         }
221
222                         free(list_del);
223                         return NOTIFICATION_ERROR_NONE;
224                 }
225                 list_del = list_del->next;
226         } while (list_del != NULL);
227
228         return NOTIFICATION_ERROR_INVALID_PARAMETER;
229 }
230
231 static void _do_deffered_task(void)
232 {
233         task_list *list_do;
234         task_list *list_temp;
235
236         if (g_task_list == NULL)
237                 return;
238
239         list_do = g_task_list;
240         g_task_list = NULL;
241
242         while (list_do->prev != NULL)
243                 list_do = list_do->prev;
244
245         while (list_do != NULL) {
246                 if (list_do->task_cb != NULL) {
247                         list_do->task_cb(list_do->data);
248                         NOTIFICATION_DBG("called:%p", list_do->task_cb);
249                 }
250                 list_temp = list_do->next;
251                 free(list_do);
252                 list_do = list_temp;
253         }
254 }
255
256 /*!
257  * functions to create operation list
258  */
259 static notification_op *_ipc_create_op(notification_op_type_e type,
260                 int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
261 {
262         int i;
263         notification_op *op_list;
264
265         if (num_op <= 0)
266                 return NULL;
267
268         op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
269
270         if (op_list == NULL) {
271                 NOTIFICATION_ERR("malloc failed");
272                 return NULL;
273         }
274
275         memset(op_list, 0x0, sizeof(notification_op) * num_op);
276
277         for (i = 0; i < num_op; i++) {
278                 (op_list + i)->type = type;
279                 if (list_priv_id != NULL)
280                         (op_list + i)->priv_id = *(list_priv_id + i);
281                 if (noti_list != NULL)
282                         (op_list + i)->noti = *(noti_list + i);
283         }
284
285         return op_list;
286 }
287
288 /*!
289  * utility functions creating notification packet
290  */
291 static inline char *_dup_string(const char *string)
292 {
293         char *ret;
294         char err_buf[ERR_BUFFER_SIZE];
295
296         if (string == NULL)
297                 return NULL;
298         if (string[0] == '\0')
299                 return NULL;
300
301         ret = strdup(string);
302         if (!ret)
303                 NOTIFICATION_ERR("Error: %s\n", strerror_r(errno, err_buf, sizeof(err_buf)));
304
305         return ret;
306 }
307
308 static inline bundle *_create_bundle_from_bundle_raw(bundle_raw *string)
309 {
310         if (string == NULL)
311                 return NULL;
312         if (string[0] == '\0')
313                 return NULL;
314
315         return bundle_decode(string, strlen((char *)string));
316 }
317
318 static void _add_noti_notify(GVariant *parameters)
319 {
320         notification_h noti;
321         notification_op *noti_op;
322         GVariant *body = NULL;
323
324         NOTIFICATION_DBG("add noti notify");
325         noti = notification_create(NOTIFICATION_TYPE_NOTI);
326         if (!noti) {
327                 NOTIFICATION_ERR("failed to create a notification");
328                 return;
329         }
330
331         g_variant_get(parameters, "(v)", &body);
332         notification_ipc_make_noti_from_gvariant(noti, body);
333         _print_noti(noti);
334         if (noti->flags_for_property & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
335                 NOTIFICATION_ERR("disable changed callback %d", noti->flags_for_property);
336                 /* Disable changed cb */
337         } else {
338                 /* Enable changed cb */
339                 noti_op = _ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, &noti);
340
341                 if (noti_op != NULL) {
342                         notification_call_changed_cb(noti_op, 1);
343                         free(noti_op);
344                 }
345         }
346         notification_free(noti);
347 }
348
349 static void _update_noti_notify(GVariant *parameters)
350 {
351         notification_h noti;
352         notification_op *noti_op;
353         GVariant *body = NULL;
354
355         noti = notification_create(NOTIFICATION_TYPE_NOTI);
356         if (!noti) {
357                 NOTIFICATION_ERR("failed to create a notification");
358                 return;
359         }
360         g_variant_get(parameters, "(v)", &body);
361         notification_ipc_make_noti_from_gvariant(noti, body);
362         _print_noti(noti);
363
364         noti_op = _ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, &noti);
365         if (noti_op != NULL) {
366                 notification_call_changed_cb(noti_op, 1);
367                 free(noti_op);
368         }
369         notification_free(noti);
370 }
371
372 static void _refresh_noti_notify(GVariant *parameters)
373 {
374         notification_op *noti_op = _ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
375
376         if (noti_op != NULL) {
377                 notification_call_changed_cb(noti_op, 1);
378                 free(noti_op);
379         }
380 }
381
382 static void _delete_single_notify(GVariant *parameters)
383 {
384         int num_deleted;
385         int priv_id;
386         notification_op *noti_op;
387
388         /* num_deleted ?? */
389         g_variant_get(parameters, "(ii)", &num_deleted, &priv_id);
390
391         noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
392         if (noti_op != NULL) {
393                 notification_call_changed_cb(noti_op, 1);
394                 free(noti_op);
395         }
396 }
397
398 static void _delete_multiple_notify(GVariant *parameters)
399 {
400         int buf[100] = {0,};
401         int idx = 0;
402         notification_op *noti_op;
403         GVariantIter *iter;
404
405         g_variant_get(parameters, "(a(i))", &iter);
406         while (g_variant_iter_loop(iter, "(i)", &buf[idx])) {
407                 NOTIFICATION_DBG("delete_noti_multiple priv_id : %d", buf[idx]);
408                 idx++;
409         }
410         g_variant_iter_free(iter);
411
412         NOTIFICATION_DBG("data num deleted:%d", idx);
413         noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, idx, buf, idx, NULL);
414
415         if (noti_op == NULL) {
416                 NOTIFICATION_ERR("_ipc_create_op failed");
417                 return;
418         }
419         notification_call_changed_cb(noti_op, idx);
420         free(noti_op);
421 }
422
423 static void _handle_noti_notify(GDBusConnection *connection,
424                 const gchar     *sender_name,
425                 const gchar     *object_path,
426                 const gchar     *interface_name,
427                 const gchar     *signal_name,
428                 GVariant        *parameters,
429                 gpointer         user_data)
430 {
431         NOTIFICATION_DBG("signal_name: %s", signal_name);
432
433         if (g_strcmp0(signal_name, "add_noti_notify") == 0)
434                 _add_noti_notify(parameters);
435         else if (g_strcmp0(signal_name, "update_noti_notify") == 0)
436                 _update_noti_notify(parameters);
437         else if (g_strcmp0(signal_name, "delete_single_notify") == 0)
438                 _delete_single_notify(parameters);
439         else if (g_strcmp0(signal_name, "delete_multiple_notify") == 0)
440                 _delete_multiple_notify(parameters);
441         else if (g_strcmp0(signal_name, "refresh_noti_notify") == 0)
442                 _refresh_noti_notify(parameters);
443 }
444
445
446 static int _dbus_signal_init()
447 {
448         int id;
449         int ret = NOTIFICATION_ERROR_NONE;
450
451         if (monitor_id == 0) {
452                 id = g_dbus_connection_signal_subscribe(_gdbus_conn,
453                                 PROVIDER_BUS_NAME,
454                                 PROVIDER_NOTI_INTERFACE_NAME,   /*      interface */
455                                 NULL,                           /*      member */
456                                 PROVIDER_OBJECT_PATH,           /*      path */
457                                 NULL,                           /*      arg0 */
458                                 G_DBUS_SIGNAL_FLAGS_NONE,
459                                 _handle_noti_notify,
460                                 NULL,
461                                 NULL);
462
463                 NOTIFICATION_DBG("subscribe id : %d", id);
464                 if (id == 0) {
465                         ret = NOTIFICATION_ERROR_IO_ERROR;
466                         NOTIFICATION_ERR("Failed to _register_noti_dbus_interface");
467                 } else {
468                         monitor_id = id;
469                         ret = NOTIFICATION_ERROR_NONE;
470                 }
471         }
472         return ret;
473 }
474
475
476 static int _dbus_init()
477 {
478         int ret = NOTIFICATION_ERROR_NONE;
479         GError *error = NULL;
480
481         if (_gdbus_conn == NULL) {
482                 _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
483
484                 if (_gdbus_conn == NULL) {
485                         if (error != NULL) {
486                                 NOTIFICATION_ERR("Failed to get dbus [%s]", error->message);
487                                 g_error_free(error);
488                         }
489                         return NOTIFICATION_ERROR_IO_ERROR;
490                 }
491                 _bus_name = g_dbus_connection_get_unique_name(_gdbus_conn);
492                 NOTIFICATION_DBG("bus name : %s", _bus_name);
493
494                 notification_error_quark();
495
496                 ret = NOTIFICATION_ERROR_NONE;
497         }
498         return ret;
499 }
500
501 static int _send_sync_noti(GVariant *body, GDBusMessage **reply, char *cmd)
502 {
503         int ret = NOTIFICATION_ERROR_NONE;
504         GError *err = NULL;
505         GDBusMessage *msg;
506
507         msg = g_dbus_message_new_method_call(
508                         PROVIDER_BUS_NAME,
509                         PROVIDER_OBJECT_PATH,
510                         PROVIDER_NOTI_INTERFACE_NAME,
511                         cmd);
512         if (!msg) {
513                 NOTIFICATION_ERR("Can't allocate new method call");
514                 if (body)
515                         g_variant_unref(body);
516                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
517         }
518
519         if (body != NULL)
520                 g_dbus_message_set_body(msg, body);
521
522         *reply = g_dbus_connection_send_message_with_reply_sync(
523                         _gdbus_conn,
524                         msg,
525                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
526                         -1,
527                         NULL,
528                         NULL,
529                         &err);
530
531         g_object_unref(msg);
532
533         if (!*reply) {
534                 ret = NOTIFICATION_ERROR_SERVICE_NOT_READY;
535                 if (err != NULL) {
536                         NOTIFICATION_ERR("No reply. cmd = %s,  error = %s", cmd, err->message);
537                         if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
538                                 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
539                         g_error_free(err);
540                 }
541                 return ret;
542         }
543
544         if (g_dbus_message_to_gerror(*reply, &err)) {
545                 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
546                         ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
547                 else
548                         ret = err->code;
549
550                 NOTIFICATION_ERR("_send_sync_noti cmd = %s, error %s, err code %d", cmd, err->message, ret);
551                 g_error_free(err);
552                 return ret;
553         }
554         NOTIFICATION_DBG("_send_sync_noti done !!");
555         return NOTIFICATION_ERROR_NONE;
556
557 }
558
559 static void _send_message_with_reply_async_cb(GDBusConnection *connection,
560                 GAsyncResult *res,
561                 gpointer user_data)
562 {
563         GVariant *body;
564         int result = NOTIFICATION_ERROR_NONE;
565         int priv_id;
566         GDBusMessage *reply = NULL;
567         GError *err = NULL;
568         result_cb_item *cb_item = (result_cb_item *)user_data;
569
570         if (cb_item == NULL) {
571                 NOTIFICATION_ERR("Failed to get a callback item");
572                 return;
573         }
574
575         reply = g_dbus_connection_send_message_with_reply_finish(
576                         connection,
577                         res,
578                         &err);
579
580         if (!reply) {
581                 if (err != NULL) {
582                         NOTIFICATION_ERR("No reply. error = %s", err->message);
583                         g_error_free(err);
584                 }
585                 result = NOTIFICATION_ERROR_SERVICE_NOT_READY;
586
587         } else if (g_dbus_message_to_gerror(reply, &err)) {
588                 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
589                         result = NOTIFICATION_ERROR_PERMISSION_DENIED;
590                 else
591                         result = err->code;
592
593                 NOTIFICATION_ERR("_send_async_noti error %s", err->message);
594                 g_error_free(err);
595         }
596
597         NOTIFICATION_DBG("_send_async_noti done !![%d]", result);
598
599         if (result == NOTIFICATION_ERROR_NONE) {
600                 body = g_dbus_message_get_body(reply);
601                 g_variant_get(body, "(i)", &priv_id);
602
603                 if (cb_item->result_cb)
604                         cb_item->result_cb(priv_id, result, cb_item->data);
605
606         } else {
607                 if (cb_item->result_cb)
608                         cb_item->result_cb(NOTIFICATION_PRIV_ID_NONE, result, cb_item->data);
609         }
610
611         if (reply)
612                 g_object_unref(reply);
613         free(cb_item);
614 }
615
616 static int _send_async_noti(GVariant *body, result_cb_item *cb_item, char *cmd)
617 {
618         GDBusMessage *msg;
619
620         msg = g_dbus_message_new_method_call(
621                         PROVIDER_BUS_NAME,
622                         PROVIDER_OBJECT_PATH,
623                         PROVIDER_NOTI_INTERFACE_NAME,
624                         cmd);
625         if (!msg) {
626                 NOTIFICATION_ERR("Can't allocate new method call");
627                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
628         }
629
630         if (body != NULL)
631                 g_dbus_message_set_body(msg, body);
632
633         g_dbus_connection_send_message_with_reply(
634                         _gdbus_conn,
635                         msg,
636                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
637                         -1,
638                         NULL,
639                         NULL,
640                         (GAsyncReadyCallback)_send_message_with_reply_async_cb,
641                         cb_item);
642
643         NOTIFICATION_DBG("_send_async_noti done !!");
644
645         g_object_unref(msg);
646         return NOTIFICATION_ERROR_NONE;
647 }
648
649 int notification_ipc_request_insert(notification_h noti, int *priv_id)
650 {
651         int result;
652         int id = NOTIFICATION_PRIV_ID_NONE;
653         GDBusMessage *reply = NULL;
654         GVariant *body;
655         GVariant *reply_body;
656
657         result = _dbus_init();
658         if (result != NOTIFICATION_ERROR_NONE) {
659                 NOTIFICATION_ERR("Can't init dbus %d", result);
660                 return result;
661         }
662
663         /* Initialize private ID */
664         noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
665         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
666         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
667
668         _print_noti(noti);
669         body = notification_ipc_make_gvariant_from_noti(noti);
670         if (body == NULL) {
671                 NOTIFICATION_ERR("cannot make gvariant");
672                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
673         }
674
675         result = _send_sync_noti(body, &reply, "add_noti");
676         NOTIFICATION_DBG("_send_sync_noti %d", result);
677
678         if (result == NOTIFICATION_ERROR_NONE) {
679                 reply_body = g_dbus_message_get_body(reply);
680                 g_variant_get(reply_body, "(i)", &id);
681
682                 if (priv_id != NULL)
683                         *priv_id = id;
684         }
685
686         if(reply)
687                 g_object_unref(reply);
688
689         NOTIFICATION_DBG("notification_ipc_request_insert done [priv_id : %d, result: %d]", id, result);
690         return result;
691 }
692
693 int notification_ipc_request_update(notification_h noti)
694 {
695         int result;
696         int priv_id = NOTIFICATION_PRIV_ID_NONE;
697
698         GDBusMessage *reply = NULL;
699         GVariant *body;
700         GVariant *reply_body;
701
702         result = _dbus_init();
703         if (result != NOTIFICATION_ERROR_NONE) {
704                 NOTIFICATION_ERR("Can't init dbus %d", result);
705                 return result;
706         }
707
708         body = notification_ipc_make_gvariant_from_noti(noti);
709         if (body == NULL) {
710                 NOTIFICATION_ERR("cannot make gvariant");
711                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
712         }
713
714         result = _send_sync_noti(body, &reply, "update_noti");
715         if (result == NOTIFICATION_ERROR_NONE) {
716                 reply_body = g_dbus_message_get_body(reply);
717                 g_variant_get(reply_body, "(i)", &priv_id);
718         }
719
720         if(reply)
721                 g_object_unref(reply);
722
723         NOTIFICATION_DBG("notification_ipc_request_update done [result: %d, priv_id :%d]", result, priv_id);
724         return result;
725 }
726
727 int notification_ipc_request_update_async(notification_h noti,
728                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
729 {
730         int result;
731         result_cb_item *cb_item;
732         GVariant *body;
733
734         result = _dbus_init();
735         if (result != NOTIFICATION_ERROR_NONE) {
736                 NOTIFICATION_ERR("Can't init dbus %d", result);
737                 return result;
738         }
739
740         cb_item = calloc(1, sizeof(result_cb_item));
741         if (cb_item == NULL)
742                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
743
744         cb_item->result_cb = result_cb;
745         cb_item->data = user_data;
746
747         body = notification_ipc_make_gvariant_from_noti(noti);
748         if (body == NULL) {
749                 NOTIFICATION_ERR("cannot make gvariant");
750                 free(cb_item);
751                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
752         }
753
754         result = _send_async_noti(body, cb_item, "update_noti");
755         NOTIFICATION_DBG("notification_ipc_request_update_async done [result: %d]", result);
756
757         if (result != NOTIFICATION_ERROR_NONE) {
758                 free(cb_item);
759                 cb_item = NULL;
760         }
761
762         g_variant_unref(body);
763
764         return result;
765 }
766
767 int notification_ipc_request_refresh(void)
768 {
769         int result;
770         GDBusMessage *reply = NULL;
771         GVariant *body;
772
773         result = _dbus_init();
774         if (result != NOTIFICATION_ERROR_NONE) {
775                 NOTIFICATION_ERR("Can't init dbus %d", result);
776                 return result;
777         }
778
779         body = g_variant_new("(i)", NOTIFICATION_OP_REFRESH);
780         result = _send_sync_noti(body, &reply, "refresh_noti");
781
782         if(reply)
783                 g_object_unref(reply);
784
785         NOTIFICATION_ERR("notification_ipc_request_refresh done [result: %d]", result);
786         return result;
787 }
788
789 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
790 {
791         int result;
792         int id;
793         GDBusMessage *reply = NULL;
794         GVariant *body;
795         GVariant *reply_body;
796
797         result = _dbus_init();
798         if (result != NOTIFICATION_ERROR_NONE) {
799                 NOTIFICATION_ERR("Can't init dbus %d", result);
800                 return result;
801         }
802
803         body = g_variant_new("(si)", pkgname, priv_id);
804         result = _send_sync_noti(body, &reply, "del_noti_single");
805
806         if (result == NOTIFICATION_ERROR_NONE) {
807                 reply_body = g_dbus_message_get_body(reply);
808                 g_variant_get(reply_body, "(i)", &id);
809         }
810
811         if(reply)
812                 g_object_unref(reply);
813
814         NOTIFICATION_ERR("notification_ipc_request_delete_single done [result: %d]", result);
815         return result;
816 }
817
818 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
819 {
820         int result;
821         int num_deleted;
822         GVariant *body;
823         GVariant *reply_body;
824         GDBusMessage *reply = NULL;
825
826         result = _dbus_init();
827         if (result != NOTIFICATION_ERROR_NONE) {
828                 NOTIFICATION_ERR("Can't init dbus %d", result);
829                 return result;
830         }
831
832         if (!pkgname)
833                 pkgname = "";
834
835         body = g_variant_new("(si)", pkgname, type);
836         result = _send_sync_noti(body, &reply, "del_noti_multiple");
837
838         if (result == NOTIFICATION_ERROR_NONE) {
839                 reply_body = g_dbus_message_get_body(reply);
840                 g_variant_get(reply_body, "(i)", &num_deleted);
841                 NOTIFICATION_ERR("num deleted:%d", num_deleted);
842         }
843
844         if(reply)
845                 g_object_unref(reply);
846
847         return result;
848 }
849
850 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
851 {
852         int result;
853         GDBusMessage *reply = NULL;
854         GVariant *body;
855         GVariant *reply_body;
856         GVariant *noti_body;
857
858         result = _dbus_init();
859         if (result != NOTIFICATION_ERROR_NONE) {
860                 NOTIFICATION_ERR("Can't init dbus %d", result);
861                 return result;
862         }
863
864         if (!pkgname)
865                 pkgname = "";
866
867         body = g_variant_new("(ss)", pkgname, tag);
868         result = _send_sync_noti(body, &reply, "load_noti_by_tag");
869
870         if (result == NOTIFICATION_ERROR_NONE) {
871                 reply_body = g_dbus_message_get_body(reply);
872                 g_variant_get(reply_body, "(v)", &noti_body);
873
874                 notification_ipc_make_noti_from_gvariant(noti, noti_body);
875                 g_variant_unref(noti_body);
876                 _print_noti(noti);
877
878         }
879
880         if(reply)
881                 g_object_unref(reply);
882
883         NOTIFICATION_DBG("notification_ipc_request_load_noti_by_tag done [result: %d]", result);
884         return result;
885 }
886
887 int notification_ipc_request_load_noti_by_priv_id(notification_h noti, const char *pkgname, int priv_id)
888 {
889         int result;
890         GDBusMessage *reply = NULL;
891         GVariant *body;
892         GVariant *reply_body;
893         GVariant *noti_body;
894
895         result = _dbus_init();
896         if (result != NOTIFICATION_ERROR_NONE) {
897                 NOTIFICATION_ERR("Can't init dbus %d", result);
898                 return result;
899         }
900
901         if (!pkgname)
902                 pkgname = "";
903
904         body = g_variant_new("(si)", pkgname, priv_id);
905         result = _send_sync_noti(body, &reply, "load_noti_by_priv_id");
906
907         if (result == NOTIFICATION_ERROR_NONE) {
908                 reply_body = g_dbus_message_get_body(reply);
909                 g_variant_get(reply_body, "(v)", &noti_body);
910
911                 notification_ipc_make_noti_from_gvariant(noti, noti_body);
912                 g_variant_unref(noti_body);
913                 _print_noti(noti);
914         }
915
916         if(reply)
917                 g_object_unref(reply);
918
919         NOTIFICATION_DBG("notification_ipc_request_load_noti_by_priv_id done [result: %d]", result);
920         return result;
921 }
922
923 int notification_ipc_request_get_count(notification_type_e type,
924                     const char *pkgname, int group_id, int priv_id, int *count)
925 {
926         int result;
927         GDBusMessage *reply = NULL;
928         GVariant *body;
929         GVariant *reply_body;
930         int re_count;
931
932         result = _dbus_init();
933         if (result != NOTIFICATION_ERROR_NONE) {
934                 NOTIFICATION_ERR("Can't init dbus %d", result);
935                 return result;
936         }
937
938         if (!pkgname)
939                 pkgname = "";
940
941         body = g_variant_new("(isii)", type, pkgname, group_id, priv_id);
942         result = _send_sync_noti(body, &reply, "get_noti_count");
943
944         if (result == NOTIFICATION_ERROR_NONE) {
945                 reply_body = g_dbus_message_get_body(reply);
946                 g_variant_get(reply_body, "(i)", &re_count);
947
948                 *count = re_count;
949                 NOTIFICATION_DBG("noti count [%d]", re_count);
950         }
951
952         if(reply)
953                 g_object_unref(reply);
954
955         NOTIFICATION_DBG("notification_ipc_request_get_count done [result: %d]", result);
956         return result;
957 }
958
959 int notification_ipc_request_load_noti_grouping_list(notification_type_e type, int count,
960                 notification_list_h *list)
961 {
962         int result;
963         GDBusMessage *reply = NULL;
964         GVariant *body;
965         GVariant *reply_body;
966         GVariant *iter_body;
967         GVariantIter *iter;
968         notification_h noti;
969         GVariant *noti_body;
970
971         result = _dbus_init();
972         if (result != NOTIFICATION_ERROR_NONE) {
973                 NOTIFICATION_ERR("Can't init dbus %d", result);
974                 return result;
975         }
976
977         body = g_variant_new("(ii)", type, count);
978         result = _send_sync_noti(body, &reply, "load_noti_grouping_list");
979
980         if (result == NOTIFICATION_ERROR_NONE) {
981                 reply_body = g_dbus_message_get_body(reply);
982                 g_variant_get(reply_body, "(a(v))", &iter);
983
984                 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
985                         noti = notification_create(NOTIFICATION_TYPE_NOTI);
986                         g_variant_get(iter_body, "(v)", &noti_body);
987                         notification_ipc_make_noti_from_gvariant(noti, noti_body);
988                         _print_noti(noti);
989                         *list = notification_list_append(*list, noti);
990                 }
991                 g_variant_iter_free(iter);
992         }
993
994         if(reply)
995                 g_object_unref(reply);
996
997         NOTIFICATION_DBG("notification_ipc_request_load_noti_grouping_list done [result: %d]", result);
998         return result;
999 }
1000
1001 int notification_ipc_request_load_noti_detail_list(const char *pkgname,
1002                 int group_id,
1003                 int priv_id,
1004                 int count,
1005                 notification_list_h *list)
1006 {
1007         int result;
1008         GDBusMessage *reply = NULL;
1009         GVariant *body;
1010         GVariant *reply_body;
1011         GVariant *iter_body;
1012         GVariantIter *iter;
1013         notification_h noti;
1014         GVariant *noti_body;
1015
1016         result = _dbus_init();
1017         if (result != NOTIFICATION_ERROR_NONE) {
1018                 NOTIFICATION_ERR("Can't init dbus %d", result);
1019                 return result;
1020         }
1021
1022         body = g_variant_new("(siii)", pkgname, group_id, priv_id, count);
1023         result = _send_sync_noti(body, &reply, "load_noti_detail_list");
1024
1025         if (result == NOTIFICATION_ERROR_NONE) {
1026                 reply_body = g_dbus_message_get_body(reply);
1027                 g_variant_get(reply_body, "(a(v))", &iter);
1028
1029                 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
1030                         noti = notification_create(NOTIFICATION_TYPE_NOTI);
1031                         g_variant_get(iter_body, "(v)", &noti_body);
1032                         notification_ipc_make_noti_from_gvariant(noti, noti_body);
1033                         _print_noti(noti);
1034                         *list = notification_list_append(*list, noti);
1035                 }
1036                 g_variant_iter_free(iter);
1037         }
1038
1039         if(reply)
1040                 g_object_unref(reply);
1041
1042         NOTIFICATION_DBG("notification_ipc_request_load_noti_detail_list done [result: %d]", result);
1043         return result;
1044 }
1045
1046 int notification_ipc_request_get_setting_array(
1047                 notification_setting_h *setting_array,
1048                 int *count)
1049 {
1050         int result;
1051         GDBusMessage *reply = NULL;
1052         GVariant *reply_body;
1053         GVariant *iter_body;
1054         GVariantIter *iter;
1055         int setting_cnt;
1056         notification_setting_h result_setting_array;
1057         notification_setting_h temp;
1058         int setting_idx;
1059
1060         result = _dbus_init();
1061         if (result != NOTIFICATION_ERROR_NONE) {
1062                 NOTIFICATION_ERR("Can't init dbus %d", result);
1063                 return result;
1064         }
1065
1066         result = _send_sync_noti(NULL, &reply, "get_setting_array");
1067
1068         if (result == NOTIFICATION_ERROR_NONE) {
1069                 reply_body = g_dbus_message_get_body(reply);
1070                 g_variant_get(reply_body, "(ia(v))", &setting_cnt, &iter);
1071
1072                 NOTIFICATION_DBG("get setting arr cnt: %d", setting_cnt);
1073                 result_setting_array = (struct notification_setting *)malloc(sizeof(struct notification_setting) * setting_cnt);
1074                 if (result_setting_array == NULL) {
1075                         NOTIFICATION_ERR("malloc failed");
1076                         g_object_unref(reply);
1077                         g_variant_iter_free(iter);
1078                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1079                 }
1080
1081                 setting_idx = 0;
1082                 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
1083                         temp = result_setting_array + setting_idx;
1084                         notification_ipc_make_setting_from_gvariant(temp, iter_body);
1085                         setting_idx++;
1086                 }
1087
1088                 *count = setting_cnt;
1089                 *setting_array = result_setting_array;
1090                 g_variant_iter_free(iter);
1091         }
1092
1093         if(reply)
1094                 g_object_unref(reply);
1095
1096         NOTIFICATION_DBG("notification_ipc_request_get_setting_array done [result: %d]", result);
1097         return result;
1098 }
1099
1100 int notification_ipc_request_get_setting_by_package_name(
1101                 const char *package_name, notification_setting_h *setting)
1102 {
1103         int result;
1104         GDBusMessage *reply = NULL;
1105         GVariant *body;
1106         GVariant *reply_body;
1107         GVariant *setting_body;
1108         notification_setting_h result_setting;
1109
1110         result = _dbus_init();
1111         if (result != NOTIFICATION_ERROR_NONE) {
1112                 NOTIFICATION_ERR("Can't init dbus %d", result);
1113                 return result;
1114         }
1115
1116         body = g_variant_new("(s)", package_name);
1117         result = _send_sync_noti(body, &reply, "get_setting_by_package_name");
1118
1119         if (result == NOTIFICATION_ERROR_NONE) {
1120                 reply_body = g_dbus_message_get_body(reply);
1121                 g_variant_get(reply_body, "(v)", &setting_body);
1122
1123                 result_setting = (struct notification_setting *)malloc(sizeof(struct notification_setting));
1124                 if (result_setting == NULL) {
1125                         NOTIFICATION_ERR("malloc failed");
1126                         g_object_unref(reply);
1127                         g_variant_unref(body);
1128                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1129                 }
1130                 notification_ipc_make_setting_from_gvariant(result_setting, setting_body);
1131
1132                 *setting = result_setting;
1133                 g_variant_unref(setting_body);
1134         }
1135
1136         if(reply)
1137                 g_object_unref(reply);
1138
1139         NOTIFICATION_DBG("notification_ipc_request_get_setting_by_package_name done [result: %d]", result);
1140         return result;
1141 }
1142
1143 int notification_ipc_request_load_system_setting(notification_system_setting_h *setting)
1144 {
1145         int result;
1146         GDBusMessage *reply = NULL;
1147         GVariant *setting_body;
1148         GVariant *reply_body;
1149         notification_system_setting_h result_setting;
1150
1151         result = _dbus_init();
1152         if (result != NOTIFICATION_ERROR_NONE) {
1153                 NOTIFICATION_ERR("Can't init dbus %d", result);
1154                 return result;
1155         }
1156
1157         result = _send_sync_noti(NULL, &reply, "load_system_setting");
1158
1159         if (result == NOTIFICATION_ERROR_NONE) {
1160                 reply_body = g_dbus_message_get_body(reply);
1161                 g_variant_get(reply_body, "(v)", &setting_body);
1162
1163                 result_setting = (struct notification_system_setting *)malloc(sizeof(struct notification_system_setting));
1164                 if (result_setting == NULL) {
1165                         NOTIFICATION_ERR("malloc failed");
1166                         g_object_unref(reply);
1167                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1168                 }
1169                 notification_ipc_make_system_setting_from_gvariant(result_setting, setting_body);
1170
1171                 *setting = result_setting;
1172                 g_variant_unref(setting_body);
1173         }
1174
1175         if(reply)
1176                 g_object_unref(reply);
1177
1178         NOTIFICATION_DBG("notification_ipc_request_load_system_setting done [result: %d]", result);
1179         return result;
1180 }
1181
1182 int notification_ipc_update_setting(notification_setting_h setting)
1183 {
1184         int result;
1185         GDBusMessage *reply = NULL;
1186         GVariant *body;
1187
1188         result = _dbus_init();
1189         if (result != NOTIFICATION_ERROR_NONE) {
1190                 NOTIFICATION_ERR("Can't init dbus %d", result);
1191                 return result;
1192         }
1193
1194         body = g_variant_new("(siii)",
1195                         setting->package_name,
1196                         (int)(setting->allow_to_notify),
1197                         (int)(setting->do_not_disturb_except),
1198                         (int)(setting->visibility_class));
1199
1200         result = _send_sync_noti(body, &reply, "update_noti_setting");
1201
1202         if(reply)
1203                 g_object_unref(reply);
1204
1205         NOTIFICATION_DBG("notification_ipc_update_setting done [result: %d]", result);
1206         return result;
1207 }
1208
1209 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1210 {
1211         int result;
1212         GDBusMessage *reply = NULL;
1213         GVariant *body;
1214
1215         result = _dbus_init();
1216         if (result != NOTIFICATION_ERROR_NONE) {
1217                 NOTIFICATION_ERR("Can't init dbus %d", result);
1218                 return result;
1219         }
1220
1221         body = g_variant_new("(ii)",
1222                         (int)(system_setting->do_not_disturb),
1223                         (int)(system_setting->visibility_class));
1224
1225         result = _send_sync_noti(body, &reply, "update_noti_sys_setting");
1226
1227         if (reply)
1228                 g_object_unref(reply);
1229
1230         NOTIFICATION_DBG("notification_ipc_update_system_setting done [result: %d]", result);
1231         return result;
1232 }
1233
1234 EXPORT_API GVariant *notification_ipc_make_gvariant_from_noti(notification_h noti)
1235 {
1236         NOTIFICATION_DBG("make gvariant from noti");
1237         int i = 0;
1238         int b_encode_len = 0;
1239         bundle_raw *args = NULL;
1240         bundle_raw *group_args = NULL;
1241         bundle_raw *b_image_path = NULL;
1242         bundle_raw *b_execute_option = NULL;
1243         bundle_raw *b_service_responding = NULL;
1244         bundle_raw *b_service_single_launch = NULL;
1245         bundle_raw *b_service_multi_launch = NULL;
1246         bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = {NULL, };
1247         bundle_raw *b_text = NULL;
1248         bundle_raw *b_key = NULL;
1249         bundle_raw *b_format_args = NULL;
1250         GVariant *body = NULL;
1251         GVariant *result_body = NULL;
1252         GVariantBuilder builder;
1253
1254         g_variant_builder_init(&builder, G_VARIANT_TYPE("a{iv}"));
1255         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NOTI_TYPE, g_variant_new_int32(noti->type));
1256         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAYOUT, g_variant_new_int32(noti->layout));
1257         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ID, g_variant_new_int32(noti->group_id));
1258         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, g_variant_new_int32(noti->internal_group_id));
1259         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PRIV_ID, g_variant_new_int32(noti->priv_id));
1260         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, g_variant_new_string((const gchar *)noti->caller_pkgname));
1261         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, g_variant_new_int32(noti->display_applist));
1262
1263         if (noti->args) {
1264                 bundle_encode(noti->args, (bundle_raw **)&args, NULL);
1265                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ARGS, g_variant_new_string((const gchar *)args));
1266
1267                 if (args)
1268                         bundle_free_encoded_rawdata(&args);
1269         }
1270
1271         if (noti->group_args) {
1272                 bundle_encode(noti->group_args, (bundle_raw **)&group_args,
1273                               &b_encode_len);
1274                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ARGS, g_variant_new_string((const gchar *)group_args));
1275
1276                 if (group_args)
1277                         bundle_free_encoded_rawdata(&group_args);
1278         }
1279
1280         if (noti->b_execute_option) {
1281                 bundle_encode(noti->b_execute_option,
1282                               (bundle_raw **)&b_execute_option, &b_encode_len);
1283                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, g_variant_new_string((const gchar *)b_execute_option));
1284
1285                 if (b_execute_option)
1286                         bundle_free_encoded_rawdata(&b_execute_option);
1287         }
1288
1289         if (noti->b_service_responding) {
1290                 bundle_encode(noti->b_service_responding,
1291                               (bundle_raw **)&b_service_responding, &b_encode_len);
1292                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, g_variant_new_string((const gchar *)b_service_responding));
1293
1294                 if (b_service_responding)
1295                         bundle_free_encoded_rawdata(&b_service_responding);
1296         }
1297
1298         if (noti->b_service_single_launch) {
1299                 bundle_encode(noti->b_service_single_launch,
1300                               (bundle_raw **)&b_service_single_launch, &b_encode_len);
1301                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, g_variant_new_string((const gchar *)b_service_single_launch));
1302
1303                 if (b_service_single_launch)
1304                         bundle_free_encoded_rawdata(&b_service_single_launch);
1305         }
1306
1307         if (noti->b_service_multi_launch) {
1308                 bundle_encode(noti->b_service_multi_launch,
1309                               (bundle_raw **)&b_service_multi_launch, &b_encode_len);
1310                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, g_variant_new_string((const gchar *)b_service_multi_launch));
1311
1312                 if (b_service_multi_launch)
1313                         bundle_free_encoded_rawdata(&b_service_multi_launch);
1314         }
1315
1316         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
1317                 if (noti->b_event_handler[i]) {
1318                         bundle_encode(noti->b_event_handler[i],
1319                                         (bundle_raw **)&b_event_handler[i], &b_encode_len);
1320                         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_BUTTON1_EVENT + i, g_variant_new_string((const gchar *)b_event_handler[i]));
1321
1322                         if (b_event_handler[i])
1323                                 bundle_free_encoded_rawdata(&b_event_handler[i]);
1324                 }
1325         }
1326
1327         if (noti->launch_pkgname)
1328                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, g_variant_new_string((const gchar *)noti->launch_pkgname));
1329
1330         if (noti->domain != NULL)
1331                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DOMAIN, g_variant_new_string((const gchar *)noti->domain));
1332
1333         if (noti->dir != NULL)
1334                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DIR, g_variant_new_string((const gchar *)noti->dir));
1335
1336         if (noti->b_text) {
1337                 bundle_encode(noti->b_text, (bundle_raw **)&b_text, &b_encode_len);
1338                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEXT, g_variant_new_string((const gchar *)b_text));
1339
1340                 if (b_text)
1341                         bundle_free_encoded_rawdata(&b_text);
1342         }
1343
1344         if (noti->b_key) {
1345                 bundle_encode(noti->b_key, (bundle_raw **)&b_key, &b_encode_len);
1346                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_KEY, g_variant_new_string((const gchar *)b_key));
1347
1348                 if (b_key)
1349                         bundle_free_encoded_rawdata(&b_key);
1350         }
1351
1352         if (noti->b_format_args) {
1353                 bundle_encode(noti->b_format_args,
1354                               (bundle_raw **)&b_format_args, &b_encode_len);
1355                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FORMAT_ARGS, g_variant_new_string((const gchar *)b_format_args));
1356
1357                 if (b_format_args)
1358                         bundle_free_encoded_rawdata(&b_format_args);
1359         }
1360
1361         if (noti->num_format_args != 0)
1362                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, g_variant_new_int32(noti->num_format_args));
1363
1364         if (noti->b_image_path) {
1365                 bundle_encode(noti->b_image_path,
1366                               (bundle_raw **)&b_image_path, &b_encode_len);
1367                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_IMAGE_PATH, g_variant_new_string((const gchar *)b_image_path));
1368
1369                 if (b_image_path)
1370                         bundle_free_encoded_rawdata(&b_image_path);
1371         }
1372
1373         if (noti->sound_type != NOTIFICATION_SOUND_TYPE_NONE)
1374                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_TYPE, g_variant_new_int32(noti->sound_type));
1375
1376         if (noti->sound_path)
1377                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_PATH, g_variant_new_string((const gchar *)noti->sound_path));
1378
1379         g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, g_variant_new_int32(noti->vibration_type));
1380
1381         if (noti->vibration_path)
1382                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_PATH, g_variant_new_string((const gchar *)noti->vibration_path));
1383
1384         if (noti->led_operation != NOTIFICATION_LED_OP_OFF)
1385                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OPERATION, g_variant_new_int32(noti->led_operation));
1386
1387         if (noti->led_argb != 0)
1388                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ARGB, g_variant_new_int32(noti->led_argb));
1389
1390         if (noti->led_on_ms != 0)
1391                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ON_MS, g_variant_new_int32(noti->led_on_ms));
1392
1393         if (noti->led_off_ms != 0)
1394                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OFF_MS, g_variant_new_int32(noti->led_off_ms));
1395
1396         if (noti->time != 0)
1397                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TIME, g_variant_new_int32(noti->time));
1398
1399         if (noti->insert_time != 0)
1400                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INSERT_TIME, g_variant_new_int32(noti->insert_time));
1401
1402         if (noti->flags_for_property != 0)
1403                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, g_variant_new_int32(noti->flags_for_property));
1404
1405         if (noti->progress_size != 0.0)
1406                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, g_variant_new_double(noti->progress_size));
1407
1408         if (noti->progress_percentage != 0.0)
1409                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, g_variant_new_double(noti->progress_percentage));
1410
1411         if (noti->app_icon_path != NULL)
1412                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_ICON_PATH, g_variant_new_string((const gchar *)noti->app_icon_path));
1413         if (noti->app_name != NULL)
1414                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_NAME, g_variant_new_string((const gchar *)noti->app_name));
1415         if (noti->temp_title != NULL)
1416                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_TITLE, g_variant_new_string((const gchar *)noti->temp_title));
1417         if (noti->temp_content != NULL)
1418                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_CONTENT, g_variant_new_string((const gchar *)noti->temp_content));
1419         if (noti->tag != NULL)
1420                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TAG, g_variant_new_string((const gchar *)noti->tag));
1421
1422         if (noti->ongoing_flag != 0)
1423                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_FLAG, g_variant_new_int32(noti->ongoing_flag));
1424         if (noti->auto_remove != 0)
1425                 g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_AUTO_REMOVE, g_variant_new_int32(noti->auto_remove));
1426
1427         result_body = g_variant_builder_end(&builder);
1428         body = g_variant_new("(v)", result_body);
1429
1430         return body;
1431 }
1432
1433 static gboolean _variant_to_int_dict(GHashTable **dict, GVariant *variant) {
1434
1435         GVariantIter iter;
1436         int key;
1437         int *hash_key;
1438         GVariant *value;
1439
1440         *dict = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, (GDestroyNotify)g_variant_unref);
1441         if (*dict == NULL)
1442                 return FALSE;
1443
1444         g_variant_iter_init(&iter, variant);
1445         while (g_variant_iter_next(&iter, "{iv}", &key, &value)) {
1446                 hash_key = (int *)calloc(sizeof(int), 1);
1447                 if (hash_key == NULL) {
1448                         g_hash_table_unref(*dict);
1449                         return FALSE;
1450                 }
1451                 *hash_key = key;
1452                 g_hash_table_insert(*dict, (gpointer)hash_key, value);
1453         }
1454         return TRUE;
1455 }
1456
1457 static gboolean _variant_dict_lookup(GHashTable *dict,
1458                 int key,
1459                 const gchar  *format_string,
1460                 ...)
1461 {
1462         GVariant *value;
1463         va_list ap;
1464
1465         value = g_hash_table_lookup(dict, (gpointer)&key);
1466
1467         if (value == NULL || !g_variant_check_format_string(value, format_string, FALSE))
1468                 return FALSE;
1469
1470         va_start(ap, format_string);
1471         g_variant_get_va(value, format_string, NULL, &ap);
1472         va_end(ap);
1473
1474         return TRUE;
1475 }
1476
1477 /*!
1478  * functions creating notification packet
1479  */
1480 EXPORT_API int notification_ipc_make_noti_from_gvariant(notification_h noti,
1481                 GVariant *variant) {
1482
1483         NOTIFICATION_DBG("make noti from GVariant");
1484         GHashTable *dict;
1485
1486         int i;
1487         char *caller_pkgname = NULL;
1488         char *launch_pkgname = NULL;
1489         bundle_raw *args = NULL;
1490         bundle_raw *group_args = NULL;
1491         bundle_raw *b_execute_option = NULL;
1492         bundle_raw *b_service_responding = NULL;
1493         bundle_raw *b_service_single_launch = NULL;
1494         bundle_raw *b_service_multi_launch = NULL;
1495         bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
1496         char *domain = NULL;
1497         char *dir = NULL;
1498         bundle_raw *b_text = NULL;
1499         bundle_raw *b_key = NULL;
1500         bundle_raw *b_format_args = NULL;
1501         bundle_raw *b_image_path = NULL;
1502         char *sound_path = NULL;
1503         char *vibration_path = NULL;
1504         char *app_icon_path = NULL;
1505         char *app_name = NULL;
1506         char *temp_title = NULL;
1507         char *temp_content = NULL;
1508         char *tag = NULL;
1509
1510         if (noti == NULL) {
1511                 NOTIFICATION_ERR("invalid data noti NULL");
1512                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1513         }
1514
1515         if (variant == NULL) {
1516                 NOTIFICATION_ERR("invalid data variant NULL");
1517                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1518         }
1519
1520         if (!_variant_to_int_dict(&dict, variant))
1521                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1522
1523         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NOTI_TYPE, "i", &noti->type);
1524         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAYOUT, "i", &noti->layout);
1525         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ID, "i", &noti->group_id);
1526         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, "i", &noti->internal_group_id);
1527         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PRIV_ID, "i", &noti->priv_id);
1528         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, "&s", &caller_pkgname);
1529         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, "&s", &launch_pkgname);
1530         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ARGS, "&s", &args);
1531         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ARGS, "&s", &group_args);
1532         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, "&s", &b_execute_option);
1533         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, "&s", &b_service_responding);
1534         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, "&s", &b_service_single_launch);
1535         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, "&s", &b_service_multi_launch);
1536         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON1_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]);
1537         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON2_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]);
1538         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON3_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]);
1539         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON4_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]);
1540         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON5_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]);
1541         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON6_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]);
1542         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ICON_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]);
1543         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_THUMBNAIL_EVENT, "&s", &noti->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]);
1544         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DOMAIN, "&s", &domain);
1545         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DIR, "&s", &dir);
1546         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEXT, "&s", &b_text);
1547         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_KEY, "&s", &b_key);
1548         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FORMAT_ARGS, "&s", &b_format_args);
1549         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, "i", &noti->num_format_args);
1550         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_IMAGE_PATH, "&s", &b_image_path);
1551         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_TYPE, "i", &noti->sound_type);
1552         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_PATH, "&s", &sound_path);
1553         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, "i", &noti->vibration_type);
1554         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_PATH, "&s", &vibration_path);
1555         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OPERATION, "i", &noti->led_operation);
1556         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ARGB, "i", &noti->led_argb);
1557         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ON_MS, "i", &noti->led_on_ms);
1558         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OFF_MS, "i", &noti->led_off_ms);
1559         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TIME, "i", &noti->time);
1560         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INSERT_TIME, "i", &noti->insert_time);
1561         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, "i", &noti->flags_for_property);
1562         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, "i", &noti->display_applist);
1563         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, "d", &noti->progress_size);
1564         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, "d", &noti->progress_percentage);
1565         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_ICON_PATH, "&s", &app_icon_path);
1566         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_NAME, "&s", &app_name);
1567         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_TITLE, "&s", &temp_title);
1568         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_CONTENT, "&s", &temp_content);
1569         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TAG, "&s", &tag);
1570         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_FLAG, "i", &noti->ongoing_flag);
1571         _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_AUTO_REMOVE, "i", &noti->auto_remove);
1572
1573         noti->caller_pkgname = _dup_string(caller_pkgname);
1574         noti->launch_pkgname = _dup_string(launch_pkgname);
1575         noti->args = _create_bundle_from_bundle_raw(args);
1576         noti->group_args = _create_bundle_from_bundle_raw(group_args);
1577         noti->b_execute_option = _create_bundle_from_bundle_raw(b_execute_option);
1578         noti->b_service_responding = _create_bundle_from_bundle_raw(
1579                         b_service_responding);
1580         noti->b_service_single_launch = _create_bundle_from_bundle_raw(
1581                         b_service_single_launch);
1582         noti->b_service_multi_launch = _create_bundle_from_bundle_raw(
1583                         b_service_multi_launch);
1584         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
1585                 noti->b_event_handler[i] = _create_bundle_from_bundle_raw(
1586                                 b_event_handler[i]);
1587         }
1588         noti->domain = _dup_string(domain);
1589         noti->dir = _dup_string(dir);
1590         noti->b_text = _create_bundle_from_bundle_raw(b_text);
1591         noti->b_key = _create_bundle_from_bundle_raw(b_key);
1592         noti->b_format_args = _create_bundle_from_bundle_raw(b_format_args);
1593         noti->b_image_path = _create_bundle_from_bundle_raw(b_image_path);
1594         noti->sound_path = _dup_string(sound_path);
1595         noti->vibration_path = _dup_string(vibration_path);
1596         noti->app_icon_path = _dup_string(app_icon_path);
1597         noti->app_name = _dup_string(app_name);
1598         noti->temp_title = _dup_string(temp_title);
1599         noti->temp_content = _dup_string(temp_content);
1600         noti->tag = _dup_string(tag);
1601
1602         g_hash_table_unref(dict);
1603
1604         return NOTIFICATION_ERROR_NONE;
1605 }
1606
1607 EXPORT_API GVariant *notification_ipc_make_gvariant_from_system_setting(struct notification_system_setting *noti_setting)
1608 {
1609         GVariant *body = NULL;
1610         body = g_variant_new("(ii)",
1611                         noti_setting->do_not_disturb,
1612                         noti_setting->visibility_class);
1613         return body;
1614 }
1615
1616 EXPORT_API int notification_ipc_make_system_setting_from_gvariant(struct notification_system_setting *noti_setting,
1617                 GVariant *variant)
1618 {
1619         int do_not_disturb;
1620         int visibility_class;
1621
1622         if (noti_setting == NULL) {
1623                 NOTIFICATION_ERR("invalid data");
1624                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1625         }
1626         g_variant_get(variant,
1627                         "(ii)",
1628                         &do_not_disturb,
1629                         &visibility_class);
1630
1631         NOTIFICATION_DBG("system setting  #### %d, %d",
1632                         do_not_disturb, visibility_class);
1633
1634         noti_setting->do_not_disturb = do_not_disturb;
1635         noti_setting->visibility_class = visibility_class;
1636
1637         NOTIFICATION_DBG("system setting2  #### %d, %d",
1638                         noti_setting->do_not_disturb, noti_setting->visibility_class);
1639
1640         return NOTIFICATION_ERROR_NONE;
1641 }
1642
1643 EXPORT_API GVariant *notification_ipc_make_gvariant_from_setting(struct notification_setting *noti_setting)
1644 {
1645         GVariant *body = NULL;
1646
1647         body = g_variant_new("(siii)",
1648                         noti_setting->package_name,
1649                         noti_setting->allow_to_notify,
1650                         noti_setting->do_not_disturb_except,
1651                         noti_setting->visibility_class);
1652
1653         return body;
1654 }
1655
1656 EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_setting *noti_setting,
1657                 GVariant *variant)
1658 {
1659         NOTIFICATION_DBG("notification_ipc_make_setting_from_gvariant !!!!");
1660         char *pkgname;
1661         int allow_to_notify;
1662         int do_not_disturb_except;
1663         int visibility_class;
1664
1665         if (noti_setting == NULL || variant == NULL) {
1666                 NOTIFICATION_ERR("invalid data");
1667                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1668         }
1669         g_variant_get(variant,
1670                         "(&siii)",
1671                         &pkgname,
1672                         &allow_to_notify,
1673                         &do_not_disturb_except,
1674                         &visibility_class);
1675
1676         NOTIFICATION_DBG("setting from variant %s !!", pkgname);
1677
1678         noti_setting->package_name = _dup_string(pkgname);
1679         noti_setting->allow_to_notify = allow_to_notify;
1680         noti_setting->do_not_disturb_except = do_not_disturb_except;
1681         noti_setting->visibility_class = visibility_class;
1682
1683         NOTIFICATION_DBG("setting from variant %s, %s",
1684                         noti_setting->package_name, pkgname);
1685
1686         return NOTIFICATION_ERROR_NONE;
1687 }
1688
1689 static int _send_service_register()
1690 {
1691         NOTIFICATION_DBG("service register");
1692         GDBusMessage *reply = NULL;
1693         int result;
1694
1695         result = _send_sync_noti(NULL, &reply, "noti_service_register");
1696
1697         if(reply)
1698                 g_object_unref(reply);
1699
1700         NOTIFICATION_ERR("_send_service_register done = %s, result = %d", _bus_name, result);
1701         return result;
1702 }
1703
1704 static int _ipc_monitor_register(void)
1705 {
1706         NOTIFICATION_ERR("register a service\n");
1707
1708         return  _send_service_register();
1709 }
1710
1711 static void _on_name_appeared(GDBusConnection *connection,
1712                 const gchar     *name,
1713                 const gchar     *name_owner,
1714                 gpointer         user_data)
1715 {
1716         NOTIFICATION_DBG("name appeared : %s", name);
1717         is_master_started = 1;
1718         _ipc_monitor_register();
1719
1720         /* TODO: dbus activation isn't enough ? */
1721         _do_deffered_task();
1722 }
1723
1724 static void _on_name_vanished(GDBusConnection *connection,
1725                 const gchar     *name,
1726                 gpointer         user_data)
1727 {
1728         NOTIFICATION_DBG("name vanished : %s", name);
1729         is_master_started = 0;
1730 }
1731
1732 int notification_ipc_monitor_init(void)
1733 {
1734         int ret;
1735
1736         ret = _dbus_init();
1737         if (ret != NOTIFICATION_ERROR_NONE) {
1738                 NOTIFICATION_ERR("Can't init dbus %d", ret);
1739                 return ret;
1740         }
1741
1742         ret = _dbus_signal_init();
1743         if (ret != NOTIFICATION_ERROR_NONE) {
1744                 NOTIFICATION_ERR("Can't signal_init %d", ret);
1745                 return ret;
1746         }
1747
1748         ret = _ipc_monitor_register();
1749         if (ret != NOTIFICATION_ERROR_NONE) {
1750                 NOTIFICATION_ERR("Can't init ipc_monitor_register %d", ret);
1751                 return ret;
1752         }
1753
1754         if (provider_monitor_id == 0) {
1755                 provider_monitor_id = g_bus_watch_name_on_connection(
1756                                 _gdbus_conn,
1757                                 PROVIDER_BUS_NAME,
1758                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
1759                                 _on_name_appeared,
1760                                 _on_name_vanished,
1761                                 NULL,
1762                                 NULL);
1763
1764                 if (provider_monitor_id == 0) {
1765                         g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id);
1766                         monitor_id = 0;
1767                         NOTIFICATION_ERR("watch on name fail");
1768                         return NOTIFICATION_ERROR_IO_ERROR;
1769                 }
1770         }
1771
1772         return NOTIFICATION_ERROR_NONE;
1773 }
1774
1775 static int _ipc_monitor_deregister(void)
1776 {
1777         if (provider_monitor_id) {
1778                 g_bus_unwatch_name(provider_monitor_id);
1779                 provider_monitor_id = 0;
1780         }
1781
1782         if (monitor_id) {
1783                 g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id);
1784                 monitor_id = 0;
1785         }
1786
1787         return NOTIFICATION_ERROR_NONE;
1788 }
1789
1790 int notification_ipc_monitor_fini(void)
1791 {
1792         return  _ipc_monitor_deregister();
1793 }