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