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