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