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