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