Set default 'display_applist' with 'NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY'
[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
27 #include <vconf.h>
28
29 #include <packet.h>
30 #include <com-core.h>
31 #include <com-core_packet.h>
32
33 #include <notification_ipc.h>
34 #include <notification_db.h>
35 #include <notification_type.h>
36 #include <notification_private.h>
37 #include <notification_debug.h>
38 #include <notification_setting_internal.h>
39
40 #define NOTIFICATION_IPC_TIMEOUT 0.0
41
42 #if !defined(VCONFKEY_MASTER_STARTED)
43 #define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
44 #endif
45
46 static struct info {
47         int server_fd;
48         int server_cl_fd;
49         int server_cl_fd_ref_cnt;
50         int client_fd;
51         const char *socket_file;
52         struct {
53                 int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
54                 void *data;
55         } server_cb;
56         int initialized;
57         int is_started_cb_set_svc;
58         int is_started_cb_set_task;
59 } s_info = {
60         .server_fd = -1,
61         .server_cl_fd = -1,
62         .server_cl_fd_ref_cnt = 0,
63         .client_fd = -1,
64         .socket_file = NOTIFICATION_ADDR,
65         .initialized = 0,
66         .is_started_cb_set_svc = 0,
67         .is_started_cb_set_task = 0,
68 };
69
70 typedef struct _task_list task_list;
71 struct _task_list {
72         task_list *prev;
73         task_list *next;
74
75         void (*task_cb) (void *data);
76         void *data;
77 };
78
79 typedef struct _result_cb_item {
80         void (*result_cb)(int priv_id, int result, void *data);
81         void *data;
82 } result_cb_item;
83
84 static task_list *g_task_list;
85
86 static int notification_ipc_monitor_register(void);
87 static int notification_ipc_monitor_deregister(void);
88 static void _do_deffered_task(void);
89 static void _master_started_cb_task(keynode_t *node, void *data);
90
91 static inline char *_string_get(char *string)
92 {
93         if (string == NULL) {
94                 return NULL;
95         }
96         if (string[0] == '\0') {
97                 return NULL;
98         }
99
100         return string;
101 }
102
103 /*!
104  * functions to check state of master
105  */
106 static inline void _set_master_started_cb(vconf_callback_fn cb) {
107         int ret = -1;
108
109         ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
110                         cb, NULL);
111         if (ret != 0) {
112                 NOTIFICATION_ERR("failed to notify key(%s) : %d",
113                                 VCONFKEY_MASTER_STARTED, ret);
114         }
115 }
116
117 static inline void _unset_master_started_cb(vconf_callback_fn cb) {
118         int ret = -1;
119
120         ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
121                         cb);
122         if (ret != 0) {
123                 NOTIFICATION_ERR("failed to notify key(%s) : %d",
124                                 VCONFKEY_MASTER_STARTED, ret);
125         }
126 }
127
128 int notification_ipc_is_master_ready(void)
129 {
130         int ret = -1, is_master_started = 0;
131
132         ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
133         if (ret == 0 && is_master_started == 1) {
134                 NOTIFICATION_ERR("the master has been started");
135         } else {
136                 is_master_started = 0;
137                 NOTIFICATION_ERR("the master has been stopped");
138         }
139
140         return is_master_started;
141 }
142
143 int
144 notification_ipc_add_deffered_task(
145                 void (*deferred_task_cb)(void *data),
146                 void *user_data)
147 {
148         task_list *list = NULL;
149         task_list *list_new = NULL;
150
151         list_new =
152             (task_list *) malloc(sizeof(task_list));
153
154         if (list_new == NULL) {
155                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
156         }
157
158         if (s_info.is_started_cb_set_task == 0) {
159                 _set_master_started_cb(_master_started_cb_task);
160                 s_info.is_started_cb_set_task = 1;
161         }
162
163         list_new->next = NULL;
164         list_new->prev = NULL;
165
166         list_new->task_cb = deferred_task_cb;
167         list_new->data = user_data;
168
169         if (g_task_list == NULL) {
170                 g_task_list = list_new;
171         } else {
172                 list = g_task_list;
173
174                 while (list->next != NULL) {
175                         list = list->next;
176                 }
177
178                 list->next = list_new;
179                 list_new->prev = list;
180         }
181         return NOTIFICATION_ERROR_NONE;
182 }
183
184 int
185 notification_ipc_del_deffered_task(
186                 void (*deferred_task_cb)(void *data))
187 {
188         task_list *list_del = NULL;
189         task_list *list_prev = NULL;
190         task_list *list_next = NULL;
191
192         list_del = g_task_list;
193
194         if (list_del == NULL) {
195                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
196         }
197
198         while (list_del->prev != NULL) {
199                 list_del = list_del->prev;
200         }
201
202         do {
203                 if (list_del->task_cb == deferred_task_cb) {
204                         list_prev = list_del->prev;
205                         list_next = list_del->next;
206
207                         if (list_prev == NULL) {
208                                 g_task_list = list_next;
209                         } else {
210                                 list_prev->next = list_next;
211                         }
212
213                         if (list_next == NULL) {
214                                 if (list_prev != NULL) {
215                                         list_prev->next = NULL;
216                                 }
217                         } else {
218                                 list_next->prev = list_prev;
219                         }
220
221                         free(list_del);
222
223                         if (g_task_list == NULL) {
224                                 if (s_info.is_started_cb_set_task == 1) {
225                                         _unset_master_started_cb(_master_started_cb_task);
226                                         s_info.is_started_cb_set_task = 0;
227                                 }
228                         }
229
230                         return NOTIFICATION_ERROR_NONE;
231                 }
232                 list_del = list_del->next;
233         } while (list_del != NULL);
234
235         return NOTIFICATION_ERROR_INVALID_PARAMETER;
236 }
237
238 static void _do_deffered_task(void) {
239         task_list *list_do = NULL;
240         task_list *list_temp = NULL;
241
242         if (g_task_list == NULL) {
243                 return;
244         }
245
246         list_do = g_task_list;
247         g_task_list = NULL;
248         if (s_info.is_started_cb_set_task == 1) {
249                 _unset_master_started_cb(_master_started_cb_task);
250                 s_info.is_started_cb_set_task = 0;
251         }
252
253         while (list_do->prev != NULL) {
254                 list_do = list_do->prev;
255         }
256
257         while (list_do != NULL) {
258                 if (list_do->task_cb != NULL) {
259                         list_do->task_cb(list_do->data);
260                         NOTIFICATION_DBG("called:%p", list_do->task_cb);
261                 }
262                 list_temp = list_do->next;
263                 free(list_do);
264                 list_do = list_temp;
265         }
266 }
267
268 static void _master_started_cb_service(keynode_t *node,
269                 void *data) {
270         int ret = NOTIFICATION_ERROR_NONE;
271
272         if (notification_ipc_is_master_ready()) {
273                 NOTIFICATION_ERR("try to register a notification service");
274                 ret = notification_ipc_monitor_deregister();
275                 if (ret != NOTIFICATION_ERROR_NONE) {
276                         NOTIFICATION_ERR("failed to unregister a monitor");
277                 }
278                 ret = notification_ipc_monitor_register();
279                 if (ret != NOTIFICATION_ERROR_NONE) {
280                         NOTIFICATION_ERR("failed to register a monitor");
281                 }
282         } else {
283                 NOTIFICATION_ERR("try to unregister a notification service");
284                 ret = notification_ipc_monitor_deregister();
285                 if (ret != NOTIFICATION_ERROR_NONE) {
286                         NOTIFICATION_ERR("failed to deregister a monitor");
287                 }
288         }
289 }
290
291 static void _master_started_cb_task(keynode_t *node,
292                 void *data) {
293
294         if (notification_ipc_is_master_ready()) {
295                 _do_deffered_task();
296         }
297 }
298
299 /*!
300  * functions to create operation list
301  */
302 notification_op *notification_ipc_create_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
303 {
304         int i = 0;
305         notification_op *op_list = NULL;
306
307         if (num_op <= 0) {
308                 return NULL;
309         }
310
311         op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
312         memset(op_list, 0x0, sizeof(notification_op) * num_op);
313
314         for (i = 0; i < num_op; i++) {
315                 (op_list + i)->type = type;
316                 if (list_priv_id != NULL) {
317                         (op_list + i)->priv_id = *(list_priv_id + i);
318                 }
319                 if (noti_list != NULL) {
320                         (op_list + i)->noti = *(noti_list + i);
321                 }
322         }
323
324         return op_list;
325 }
326
327 /*!
328  * utility functions creating notification packet
329  */
330 static inline char *_dup_string(const char *string)
331 {
332         char *ret;
333
334         if (string == NULL) {
335                 return NULL;
336         }
337         if (string[0] == '\0') {
338                 return NULL;
339         }
340
341         ret = strdup(string);
342         if (!ret)
343                 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
344
345         return ret;
346 }
347
348 static inline bundle *_create_bundle_from_string(unsigned char *string)
349 {
350         if (string == NULL) {
351                 return NULL;
352         }
353         if (string[0] == '\0') {
354                 return NULL;
355         }
356
357         return bundle_decode(string, strlen((char *)string));
358 }
359
360 /*!
361  * functions creating notification packet
362  */
363 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
364 {
365         int i = 0;
366         int ret = 0;
367         int type;
368         int layout;
369         int group_id;
370         int internal_group_id;
371         int priv_id;
372         char *caller_pkgname = NULL;
373         char *launch_pkgname = NULL;
374         unsigned char *args = NULL;
375         unsigned char *group_args = NULL;
376         unsigned char *b_execute_option = NULL;
377         unsigned char *b_service_responding = NULL;
378         unsigned char *b_service_single_launch = NULL;
379         unsigned char *b_service_multi_launch = NULL;
380         unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
381         char *domain = NULL;
382         char *dir = NULL;
383         unsigned char *b_text = NULL;
384         unsigned char *b_key = NULL;
385         unsigned char *b_format_args = NULL;
386         int num_format_args;
387         unsigned char *b_image_path = NULL;
388         int sound_type;
389         char *sound_path = NULL;
390         int vibration_type;
391         char *vibration_path = NULL;
392         int led_operation;
393         int led_argb;
394         int led_on_ms;
395         int led_off_ms;
396         time_t time;
397         time_t insert_time;
398         int flags_for_property;
399         int display_applist;
400         double progress_size;
401         double progress_percentage;
402         char *app_icon_path = NULL;
403         char *app_name = NULL;
404         char *temp_title = NULL;
405         char *temp_content = NULL;
406         char *tag = NULL;
407
408         if (noti == NULL) {
409                 NOTIFICATION_ERR("invalid data");
410                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
411         }
412
413         ret = packet_get(packet,
414                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
415                         &type,
416                         &layout,
417                         &group_id,
418                         &internal_group_id,
419                         &priv_id,
420                         &caller_pkgname,
421                         &launch_pkgname,
422                         &args,
423                         &group_args,
424                         &b_execute_option,
425                         &b_service_responding,
426                         &b_service_single_launch,
427                         &b_service_multi_launch,
428                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1],
429                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2],
430                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3],
431                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4],
432                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5],
433                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6],
434                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON],
435                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL],
436                         &domain,
437                         &dir,
438                         &b_text,
439                         &b_key,
440                         &b_format_args,
441                         &num_format_args,
442                         &b_image_path,
443                         &sound_type,
444                         &sound_path,
445                         &vibration_type,
446                         &vibration_path,
447                         &led_operation,
448                         &led_argb,
449                         &led_on_ms,
450                         &led_off_ms,
451                         &time,
452                         &insert_time,
453                         &flags_for_property,
454                         &display_applist,
455                         &progress_size,
456                         &progress_percentage,
457                         &app_icon_path,
458                         &app_name,
459                         &temp_title,
460                         &temp_content,
461                         &tag);
462
463         if (ret != 47) {
464                 NOTIFICATION_ERR("failed to create a noti from packet");
465                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
466         }
467
468         /*!
469          * This is already allocated from the notification_create function.
470          * Before reallocate string to here.
471          * We have to release old one first.
472          */
473         free(noti->caller_pkgname);
474         noti->caller_pkgname = _dup_string(caller_pkgname);
475         noti->launch_pkgname = _dup_string(launch_pkgname);
476         noti->args = _create_bundle_from_string(args);
477         noti->group_args = _create_bundle_from_string(group_args);
478         noti->b_execute_option = _create_bundle_from_string(b_execute_option);
479         noti->b_service_responding = _create_bundle_from_string(b_service_responding);
480         noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
481         noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
482         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
483                 noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]);
484         }
485         noti->domain = _dup_string(domain);
486         noti->dir = _dup_string(dir);
487         noti->b_text = _create_bundle_from_string(b_text);
488         noti->b_key = _create_bundle_from_string(b_key);
489         noti->b_format_args = _create_bundle_from_string(b_format_args);
490         noti->b_image_path = _create_bundle_from_string(b_image_path);
491         noti->sound_path = _dup_string(sound_path);
492         noti->vibration_path = _dup_string(vibration_path);
493         noti->app_icon_path = _dup_string(app_icon_path);
494         noti->app_name = _dup_string(app_name);
495         noti->temp_title = _dup_string(temp_title);
496         noti->temp_content = _dup_string(temp_content);
497
498         noti->type = type;
499         noti->layout = layout;
500         noti->group_id = group_id;
501         noti->internal_group_id = internal_group_id;
502         noti->priv_id = priv_id;
503         noti->num_format_args = num_format_args;
504         noti->sound_type = sound_type;
505         noti->vibration_type = vibration_type;
506         noti->led_operation = led_operation;
507         noti->led_argb = led_argb;
508         noti->led_on_ms = led_on_ms;
509         noti->led_off_ms = led_off_ms;
510         noti->time = time;
511         noti->insert_time = insert_time;
512         noti->flags_for_property = flags_for_property;
513         noti->display_applist = display_applist;
514         noti->progress_size = progress_size;
515         noti->progress_percentage = progress_percentage;
516         noti->tag = _dup_string(tag);
517
518         return NOTIFICATION_ERROR_NONE;
519 }
520
521 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
522 {
523         int i = 0;
524         int b_encode_len = 0;
525         struct packet *result = NULL;
526         char *args = NULL;
527         char *group_args = NULL;
528         char *b_image_path = NULL;
529         char *b_execute_option = NULL;
530         char *b_service_responding = NULL;
531         char *b_service_single_launch = NULL;
532         char *b_service_multi_launch = NULL;
533         char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
534         char *b_text = NULL;
535         char *b_key = NULL;
536         char *b_format_args = NULL;
537         struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
538         const char *title_key = NULL;
539         char buf_key[32] = { 0, };
540
541         /* Decode bundle to insert DB */
542         if (noti->args) {
543                 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
544         }
545         if (noti->group_args) {
546                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
547                               &b_encode_len);
548         }
549
550         if (noti->b_execute_option) {
551                 bundle_encode(noti->b_execute_option,
552                               (bundle_raw **) & b_execute_option, &b_encode_len);
553         }
554         if (noti->b_service_responding) {
555                 bundle_encode(noti->b_service_responding,
556                               (bundle_raw **) & b_service_responding, &b_encode_len);
557         }
558         if (noti->b_service_single_launch) {
559                 bundle_encode(noti->b_service_single_launch,
560                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
561         }
562         if (noti->b_service_multi_launch) {
563                 bundle_encode(noti->b_service_multi_launch,
564                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
565         }
566
567         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
568                 if (noti->b_event_handler[i]) {
569                         bundle_encode(noti->b_event_handler[i],
570                                         (bundle_raw **) & b_event_handler[i], &b_encode_len);
571                 }
572         }
573
574         if (noti->b_text) {
575                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
576         }
577         if (noti->b_key) {
578                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
579         }
580         if (noti->b_format_args) {
581                 bundle_encode(noti->b_format_args,
582                               (bundle_raw **) & b_format_args, &b_encode_len);
583         }
584
585         if (noti->b_image_path) {
586                 bundle_encode(noti->b_image_path,
587                               (bundle_raw **) & b_image_path, &b_encode_len);
588         }
589
590         if (noti->b_key != NULL) {
591                 snprintf(buf_key, sizeof(buf_key), "%d",
592                          NOTIFICATION_TEXT_TYPE_TITLE);
593
594                 title_key = bundle_get_val(noti->b_key, buf_key);
595         }
596
597         if (title_key == NULL && noti->b_text != NULL) {
598                 snprintf(buf_key, sizeof(buf_key), "%d",
599                          NOTIFICATION_TEXT_TYPE_TITLE);
600
601                 title_key = bundle_get_val(noti->b_text, buf_key);
602         }
603
604         if (title_key == NULL) {
605                 title_key = noti->caller_pkgname;
606         }
607
608         if (packet_type == 1)
609                 func_to_create_packet = packet_create;
610         else if (packet_type == 2)
611                 func_to_create_packet = packet_create_noack;
612         else {
613                 goto out;
614         }
615
616         result = func_to_create_packet(command,
617                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
618                         noti->type,
619                         noti->layout,
620                         noti->group_id,
621                         noti->internal_group_id,
622                         noti->priv_id,
623                         NOTIFICATION_CHECK_STR(noti->caller_pkgname),
624                         NOTIFICATION_CHECK_STR(noti->launch_pkgname),
625                         NOTIFICATION_CHECK_STR(args),
626                         NOTIFICATION_CHECK_STR(group_args),
627                         NOTIFICATION_CHECK_STR(b_execute_option),
628                         NOTIFICATION_CHECK_STR(b_service_responding),
629                         NOTIFICATION_CHECK_STR(b_service_single_launch),
630                         NOTIFICATION_CHECK_STR(b_service_multi_launch),
631                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
632                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
633                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
634                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
635                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
636                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
637                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
638                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
639                         NOTIFICATION_CHECK_STR(noti->domain),
640                         NOTIFICATION_CHECK_STR(noti->dir),
641                         NOTIFICATION_CHECK_STR(b_text),
642                         NOTIFICATION_CHECK_STR(b_key),
643                         NOTIFICATION_CHECK_STR(b_format_args),
644                         noti->num_format_args,
645                         NOTIFICATION_CHECK_STR(b_image_path),
646                         noti->sound_type,
647                         NOTIFICATION_CHECK_STR(noti->sound_path),
648                         noti->vibration_type,
649                         NOTIFICATION_CHECK_STR(noti->vibration_path),
650                         noti->led_operation,
651                         noti->led_argb,
652                         noti->led_on_ms,
653                         noti->led_off_ms,
654                         noti->time,
655                         noti->insert_time,
656                         noti->flags_for_property,
657                         noti->display_applist,
658                         noti->progress_size,
659                         noti->progress_percentage,
660                         NOTIFICATION_CHECK_STR(noti->app_icon_path),
661                         NOTIFICATION_CHECK_STR(noti->app_name),
662                         NOTIFICATION_CHECK_STR(noti->temp_title),
663                         NOTIFICATION_CHECK_STR(noti->temp_content),
664                         NOTIFICATION_CHECK_STR(noti->tag));
665
666 out:
667         /* Free decoded data */
668         if (args) {
669                 free(args);
670         }
671         if (group_args) {
672                 free(group_args);
673         }
674
675         if (b_execute_option) {
676                 free(b_execute_option);
677         }
678         if (b_service_responding) {
679                 free(b_service_responding);
680         }
681         if (b_service_single_launch) {
682                 free(b_service_single_launch);
683         }
684         if (b_service_multi_launch) {
685                 free(b_service_multi_launch);
686         }
687
688         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
689                 if (b_event_handler[i]) {
690                         free(b_event_handler[i]);
691                 }
692         }
693
694         if (b_text) {
695                 free(b_text);
696         }
697         if (b_key) {
698                 free(b_key);
699         }
700         if (b_format_args) {
701                 free(b_format_args);
702         }
703
704         if (b_image_path) {
705                 free(b_image_path);
706         }
707
708         return result;
709 }
710
711 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
712 {
713         int i = 0;
714         int b_encode_len = 0;
715         struct packet *result = NULL;
716         char *args = NULL;
717         char *group_args = NULL;
718         char *b_image_path = NULL;
719         char *b_execute_option = NULL;
720         char *b_service_responding = NULL;
721         char *b_service_single_launch = NULL;
722         char *b_service_multi_launch = NULL;
723         char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
724         char *b_text = NULL;
725         char *b_key = NULL;
726         char *b_format_args = NULL;
727         const char *title_key = NULL;
728         char buf_key[32] = { 0, };
729
730         /* Decode bundle to insert DB */
731         if (noti->args) {
732                 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
733         }
734         if (noti->group_args) {
735                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
736                               &b_encode_len);
737         }
738
739         if (noti->b_execute_option) {
740                 bundle_encode(noti->b_execute_option,
741                               (bundle_raw **) & b_execute_option, &b_encode_len);
742         }
743         if (noti->b_service_responding) {
744                 bundle_encode(noti->b_service_responding,
745                               (bundle_raw **) & b_service_responding, &b_encode_len);
746         }
747         if (noti->b_service_single_launch) {
748                 bundle_encode(noti->b_service_single_launch,
749                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
750         }
751         if (noti->b_service_multi_launch) {
752                 bundle_encode(noti->b_service_multi_launch,
753                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
754         }
755
756         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
757                 if (noti->b_event_handler[i]) {
758                         bundle_encode(noti->b_event_handler[i],
759                                         (bundle_raw **) & b_event_handler[i], &b_encode_len);
760                 }
761         }
762
763         if (noti->b_text) {
764                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
765         }
766         if (noti->b_key) {
767                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
768         }
769         if (noti->b_format_args) {
770                 bundle_encode(noti->b_format_args,
771                               (bundle_raw **) & b_format_args, &b_encode_len);
772         }
773
774         if (noti->b_image_path) {
775                 bundle_encode(noti->b_image_path,
776                               (bundle_raw **) & b_image_path, &b_encode_len);
777         }
778
779         if (noti->b_key != NULL) {
780                 snprintf(buf_key, sizeof(buf_key), "%d",
781                          NOTIFICATION_TEXT_TYPE_TITLE);
782
783                 title_key = bundle_get_val(noti->b_key, buf_key);
784         }
785
786         if (title_key == NULL && noti->b_text != NULL) {
787                 snprintf(buf_key, sizeof(buf_key), "%d",
788                          NOTIFICATION_TEXT_TYPE_TITLE);
789
790                 title_key = bundle_get_val(noti->b_text, buf_key);
791         }
792
793         if (title_key == NULL) {
794                 title_key = noti->caller_pkgname;
795         }
796
797         result = packet_create_reply(packet,
798                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssss",
799                         noti->type,
800                         noti->layout,
801                         noti->group_id,
802                         noti->internal_group_id,
803                         noti->priv_id,
804                         NOTIFICATION_CHECK_STR(noti->caller_pkgname),
805                         NOTIFICATION_CHECK_STR(noti->launch_pkgname),
806                         NOTIFICATION_CHECK_STR(args),
807                         NOTIFICATION_CHECK_STR(group_args),
808                         NOTIFICATION_CHECK_STR(b_execute_option),
809                         NOTIFICATION_CHECK_STR(b_service_responding),
810                         NOTIFICATION_CHECK_STR(b_service_single_launch),
811                         NOTIFICATION_CHECK_STR(b_service_multi_launch),
812                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
813                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
814                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
815                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
816                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
817                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
818                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
819                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
820                         NOTIFICATION_CHECK_STR(noti->domain),
821                         NOTIFICATION_CHECK_STR(noti->dir),
822                         NOTIFICATION_CHECK_STR(b_text),
823                         NOTIFICATION_CHECK_STR(b_key),
824                         NOTIFICATION_CHECK_STR(b_format_args),
825                         noti->num_format_args,
826                         NOTIFICATION_CHECK_STR(b_image_path),
827                         noti->sound_type,
828                         NOTIFICATION_CHECK_STR(noti->sound_path),
829                         noti->vibration_type,
830                         NOTIFICATION_CHECK_STR(noti->vibration_path),
831                         noti->led_operation,
832                         noti->led_argb,
833                         noti->led_on_ms,
834                         noti->led_off_ms,
835                         noti->time,
836                         noti->insert_time,
837                         noti->flags_for_property,
838                         noti->display_applist,
839                         noti->progress_size,
840                         noti->progress_percentage,
841                         NOTIFICATION_CHECK_STR(noti->app_icon_path),
842                         NOTIFICATION_CHECK_STR(noti->app_name),
843                         NOTIFICATION_CHECK_STR(noti->temp_title),
844                         NOTIFICATION_CHECK_STR(noti->temp_content),
845                         NOTIFICATION_CHECK_STR(noti->tag));
846
847         /* Free decoded data */
848         if (args) {
849                 free(args);
850         }
851         if (group_args) {
852                 free(group_args);
853         }
854
855         if (b_execute_option) {
856                 free(b_execute_option);
857         }
858         if (b_service_responding) {
859                 free(b_service_responding);
860         }
861         if (b_service_single_launch) {
862                 free(b_service_single_launch);
863         }
864         if (b_service_multi_launch) {
865                 free(b_service_multi_launch);
866         }
867
868         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
869                 if (b_event_handler[i]) {
870                         free(b_event_handler[i]);
871                 }
872         }
873
874         if (b_text) {
875                 free(b_text);
876         }
877         if (b_key) {
878                 free(b_key);
879         }
880         if (b_format_args) {
881                 free(b_format_args);
882         }
883
884         if (b_image_path) {
885                 free(b_image_path);
886         }
887
888         return result;
889 }
890
891 /*!
892  * functions to handler services
893  */
894 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
895 {
896         notification_h noti = NULL;
897
898         if (!packet) {
899                 NOTIFICATION_ERR("a packet is null");
900                 return NULL;
901         }
902         noti = notification_create(NOTIFICATION_TYPE_NOTI);
903         if (!noti) {
904                 NOTIFICATION_ERR("failed to create a notification");
905                 return NULL;
906         }
907         notification_ipc_make_noti_from_packet(noti, packet);
908
909         if (noti->flags_for_property
910                 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
911                 /* Disable changed cb */
912         } else {
913                 /* Enable changed cb */
914                 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, &noti);
915                 if (noti_op != NULL) {
916                         notification_call_changed_cb(noti_op, 1);
917                         free(noti_op);
918                 }
919         }
920         notification_free(noti);
921
922         return NULL;
923 }
924
925 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
926 {
927         notification_h noti = NULL;
928
929         if (!packet) {
930                 NOTIFICATION_ERR("a packet is null");
931                 return NULL;
932         }
933
934         noti = notification_create(NOTIFICATION_TYPE_NOTI);
935         if (!noti) {
936                 NOTIFICATION_ERR("failed to create a notification");
937                 return NULL;
938         }
939
940         notification_ipc_make_noti_from_packet(noti, packet);
941
942         notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, &noti);
943         if (noti_op != NULL) {
944                 notification_call_changed_cb(noti_op, 1);
945                 free(noti_op);
946         }
947
948         notification_free(noti);
949
950         return NULL;
951 }
952
953 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
954 {
955         if (!packet) {
956                 NOTIFICATION_ERR("a packet is null");
957                 return NULL;
958         }
959         notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
960         if (noti_op != NULL) {
961                 notification_call_changed_cb(noti_op, 1);
962                 free(noti_op);
963         }
964
965         return NULL;
966 }
967
968 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
969 {
970         int num_deleted = 0;
971         int priv_id = NOTIFICATION_PRIV_ID_NONE;
972
973         if (!packet) {
974                 NOTIFICATION_ERR("a packet is null");
975                 return NULL;
976         }
977         if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
978                 notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
979                 if (noti_op != NULL) {
980                         notification_call_changed_cb(noti_op, 1);
981                         free(noti_op);
982                 }
983         }
984
985         return NULL;
986 }
987
988 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
989 {
990         int ret = 0;
991         int buf[10] = {0,};
992         int num_deleted = 0;
993
994         NOTIFICATION_INFO("delete_noti_multiple");
995
996         if (!packet) {
997                 NOTIFICATION_ERR("a packet is null");
998                 return NULL;
999         }
1000         ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
1001                         &(buf[0]),
1002                         &(buf[1]),
1003                         &(buf[2]),
1004                         &(buf[3]),
1005                         &(buf[4]),
1006                         &(buf[5]),
1007                         &(buf[6]),
1008                         &(buf[7]),
1009                         &(buf[8]),
1010                         &(buf[9]));
1011
1012         NOTIFICATION_INFO("packet data count:%d", ret);
1013         NOTIFICATION_INFO("packet data num deleted:%d", num_deleted);
1014
1015         int i = 0;
1016         for (i = 0 ; i < 10 ; i++) {
1017                 NOTIFICATION_INFO("packet data[%d]:%d",i, buf[i]);
1018         }
1019
1020         if (ret == 11) {
1021                 notification_op *noti_op = notification_ipc_create_op(
1022                                 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
1023                 if (noti_op == NULL) {
1024                         NOTIFICATION_ERR("notification_ipc_create_op failed");
1025                         return NULL;
1026                 }
1027                 notification_call_changed_cb(noti_op, num_deleted);
1028                 free(noti_op);
1029         }
1030
1031         return NULL;
1032 }
1033
1034 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
1035 {
1036         int ret;
1037
1038         if (!packet) {
1039                 NOTIFICATION_ERR("Packet is not valid\n");
1040                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1041         } else if (packet_get(packet, "i", &ret) != 1) {
1042                 NOTIFICATION_ERR("Packet is not valid\n");
1043                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1044         } else {
1045                 if (ret == 0) {
1046                         notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1047                         if (noti_op != NULL) {
1048                                 notification_call_changed_cb(noti_op, 1);
1049                                 free(noti_op);
1050                         }
1051                 }
1052         }
1053         return ret;
1054 }
1055
1056 /*!
1057  * functions to initialize and register a monitor
1058  */
1059 static int notification_ipc_monitor_register(void)
1060 {
1061         int ret;
1062         struct packet *packet;
1063         static struct method service_table[] = {
1064                 {
1065                         .cmd = "add_noti",
1066                         .handler = _handler_insert,
1067                 },
1068                 {
1069                         .cmd = "update_noti",
1070                         .handler = _handler_update,
1071                 },
1072                 {
1073                         .cmd = "refresh_noti",
1074                         .handler = _handler_refresh,
1075                 },
1076                 {
1077                         .cmd = "del_noti_single",
1078                         .handler = _handler_delete_single,
1079                 },
1080                 {
1081                         .cmd = "del_noti_multiple",
1082                         .handler = _handler_delete_multiple,
1083                 },
1084                 {
1085                         .cmd = NULL,
1086                         .handler = NULL,
1087                 },
1088         };
1089
1090         if (s_info.initialized == 1) {
1091                 return NOTIFICATION_ERROR_NONE;
1092         } else {
1093                 s_info.initialized = 1;
1094         }
1095
1096         NOTIFICATION_ERR("register a service\n");
1097
1098         com_core_packet_use_thread(1);
1099         s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1100         if (s_info.server_fd < 0) {
1101                 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1102                 return NOTIFICATION_ERROR_IO_ERROR;
1103         }
1104
1105         packet = packet_create("service_register", "");
1106         if (!packet) {
1107                 NOTIFICATION_ERR("Failed to build a packet\n");
1108                 com_core_packet_client_fini(s_info.server_fd);
1109                 return NOTIFICATION_ERROR_IO_ERROR;
1110         }
1111
1112         ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1113         NOTIFICATION_DBG("Service register sent: %d\n", ret);
1114         packet_destroy(packet);
1115         if (ret != 0) {
1116                 com_core_packet_client_fini(s_info.server_fd);
1117                 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1118                 ret = NOTIFICATION_ERROR_IO_ERROR;
1119         } else {
1120                 ret = NOTIFICATION_ERROR_NONE;
1121         }
1122
1123         NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1124         return ret;
1125 }
1126
1127 int notification_ipc_monitor_deregister(void)
1128 {
1129         if (s_info.initialized == 0) {
1130                 return NOTIFICATION_ERROR_NONE;
1131         }
1132
1133         com_core_packet_client_fini(s_info.server_fd);
1134         s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1135
1136         s_info.initialized = 0;
1137
1138         return NOTIFICATION_ERROR_NONE;
1139 }
1140
1141 int notification_ipc_monitor_init(void)
1142 {
1143         int ret = NOTIFICATION_ERROR_NONE;
1144
1145         if (notification_ipc_is_master_ready()) {
1146                 ret = notification_ipc_monitor_register();
1147         }
1148
1149         if (s_info.is_started_cb_set_svc == 0) {
1150                 _set_master_started_cb(_master_started_cb_service);
1151                 s_info.is_started_cb_set_svc = 1;
1152         }
1153
1154         return ret;
1155 }
1156
1157 int notification_ipc_monitor_fini(void)
1158 {
1159         int ret = NOTIFICATION_ERROR_NONE;
1160
1161         if (s_info.is_started_cb_set_svc == 1) {
1162                 _unset_master_started_cb(_master_started_cb_service);
1163                 s_info.is_started_cb_set_svc = 0;
1164         }
1165
1166         ret = notification_ipc_monitor_deregister();
1167
1168         return ret;
1169 }
1170
1171 /*!
1172  * functions to request the service
1173  */
1174 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1175 {
1176         int status = 0;
1177         int id = NOTIFICATION_PRIV_ID_NONE;
1178         struct packet *packet;
1179         struct packet *result;
1180
1181         /* Initialize private ID */
1182         noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1183         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1184         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1185
1186         packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1187         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1188                         packet,
1189                         NOTIFICATION_IPC_TIMEOUT);
1190         packet_destroy(packet);
1191
1192         if (result != NULL) {
1193                 if (packet_get(result, "ii", &status, &id) != 2) {
1194                         NOTIFICATION_ERR("Failed to get a result packet");
1195                         packet_unref(result);
1196                         return NOTIFICATION_ERROR_IO_ERROR;
1197                 }
1198
1199                 if (status != NOTIFICATION_ERROR_NONE) {
1200                         packet_unref(result);
1201                         return status;
1202                 }
1203                 packet_unref(result);
1204         } else {
1205                 NOTIFICATION_ERR("failed to receive answer(insert)");
1206                 if (notification_ipc_is_master_ready() == 1) {
1207                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1208                 }
1209                 else {
1210                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1211                 }
1212         }
1213
1214         if (priv_id != NULL) {
1215                 *priv_id = id;
1216         }
1217
1218         return NOTIFICATION_ERROR_NONE;
1219 }
1220
1221 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1222 {
1223         int status = 0;
1224         int id = NOTIFICATION_PRIV_ID_NONE;
1225         struct packet *packet;
1226         struct packet *result;
1227
1228         packet = packet_create("del_noti_single", "si", pkgname, priv_id);
1229         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1230                         packet,
1231                         NOTIFICATION_IPC_TIMEOUT);
1232         packet_destroy(packet);
1233
1234         if (result != NULL) {
1235                 if (packet_get(result, "ii", &status, &id) != 2) {
1236                         NOTIFICATION_ERR("Failed to get a result packet");
1237                         packet_unref(result);
1238                         return NOTIFICATION_ERROR_IO_ERROR;
1239                 }
1240                 packet_unref(result);
1241         } else {
1242                 NOTIFICATION_ERR("failed to receive answer(delete)");
1243                 if (notification_ipc_is_master_ready() == 1) {
1244                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1245                 }
1246                 else {
1247                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1248                 }
1249         }
1250
1251         return status;
1252 }
1253
1254 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1255 {
1256         int status = 0;
1257         int num_deleted = 0;
1258         struct packet *packet;
1259         struct packet *result;
1260
1261         packet = packet_create("del_noti_multiple", "si", pkgname, type);
1262         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1263                         packet,
1264                         NOTIFICATION_IPC_TIMEOUT);
1265         packet_destroy(packet);
1266
1267         if (result != NULL) {
1268                 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1269                         NOTIFICATION_ERR("Failed to get a result packet");
1270                         packet_unref(result);
1271                         return NOTIFICATION_ERROR_IO_ERROR;
1272                 }
1273                 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1274                 packet_unref(result);
1275         } else {
1276                 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1277                 if (notification_ipc_is_master_ready() == 1) {
1278                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1279                 }
1280                 else {
1281                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1282                 }
1283         }
1284
1285         return status;
1286 }
1287
1288 int notification_ipc_request_update(notification_h noti)
1289 {
1290         int status = 0;
1291         int id = NOTIFICATION_PRIV_ID_NONE;
1292         struct packet *packet;
1293         struct packet *result;
1294
1295         packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1296         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1297                         packet,
1298                         NOTIFICATION_IPC_TIMEOUT);
1299         packet_destroy(packet);
1300
1301         if (result != NULL) {
1302                 if (packet_get(result, "ii", &status, &id) != 2) {
1303                         NOTIFICATION_ERR("Failed to get a result packet");
1304                         packet_unref(result);
1305                         return NOTIFICATION_ERROR_IO_ERROR;
1306                 }
1307                 packet_unref(result);
1308         } else {
1309                 NOTIFICATION_ERR("failed to receive answer(update)");
1310                 if (notification_ipc_is_master_ready() == 1) {
1311                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1312                 }
1313                 else {
1314                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1315                 }
1316         }
1317
1318         return status;
1319 }
1320
1321 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1322 {
1323         int status = 0;
1324         int id = NOTIFICATION_PRIV_ID_NONE;
1325         result_cb_item *cb_item = (result_cb_item *)data;
1326
1327         if (cb_item == NULL) {
1328                 NOTIFICATION_ERR("Failed to get a callback item");
1329                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1330         }
1331         s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1332         if (s_info.server_cl_fd_ref_cnt <= 0) {
1333                 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1334                 int fd_temp = s_info.server_cl_fd;
1335                 s_info.server_cl_fd = -1;
1336                 com_core_packet_client_fini(fd_temp);
1337                 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1338         }
1339
1340         if (packet != NULL) {
1341                 if (packet_get(packet, "ii", &status, &id) != 2) {
1342                         NOTIFICATION_ERR("Failed to get a result packet");
1343                         status = NOTIFICATION_ERROR_IO_ERROR;
1344                 }
1345         }
1346
1347         if (cb_item->result_cb != NULL) {
1348                 cb_item->result_cb(id, status, cb_item->data);
1349         }
1350         free(cb_item);
1351
1352         return status;
1353 }
1354
1355 int notification_ipc_request_update_async(notification_h noti,
1356                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1357 {
1358         int ret = NOTIFICATION_ERROR_NONE;
1359         int ret_con = 0;
1360         struct packet *packet = NULL;
1361         result_cb_item *cb_item = NULL;
1362
1363         packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1364         if (packet == NULL) {
1365                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1366                 goto fail;
1367         }
1368
1369         cb_item = calloc(1, sizeof(result_cb_item));
1370         if (cb_item == NULL) {
1371                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1372                 goto fail;
1373         }
1374
1375         if (s_info.server_cl_fd < 0) {
1376                 com_core_packet_use_thread(1);
1377                 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1378                 if (s_info.server_cl_fd < 0) {
1379                         NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1380                 if (notification_ipc_is_master_ready() == 1) {
1381                         ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1382                 }
1383                 else {
1384                         ret =  NOTIFICATION_ERROR_SERVICE_NOT_READY;
1385                 }
1386                         goto fail;
1387                 }
1388                 s_info.server_cl_fd_ref_cnt = 1;
1389         } else {
1390                 s_info.server_cl_fd_ref_cnt++;
1391         }
1392
1393         cb_item->result_cb = result_cb;
1394         cb_item->data = user_data;
1395
1396         NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1397
1398         ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1399                         _notification_ipc_update_cb, cb_item);
1400         if (ret_con < 0) {
1401                 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1402                 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1403                 if (s_info.server_cl_fd_ref_cnt <= 0) {
1404                         int fd_temp = s_info.server_cl_fd;
1405                         s_info.server_cl_fd = -1;
1406                         com_core_packet_client_fini(fd_temp);
1407                         NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1408                 }
1409                 ret = NOTIFICATION_ERROR_IO_ERROR;
1410                 goto fail;
1411         } else {
1412                 ret = NOTIFICATION_ERROR_NONE;
1413                 goto success;
1414         }
1415
1416 fail:
1417         if (cb_item) free(cb_item);
1418         NOTIFICATION_ERR("Err: %d\n", ret);
1419
1420 success:
1421         if (packet) packet_destroy(packet);
1422
1423         return ret;
1424 }
1425
1426 int notification_ipc_request_refresh(void)
1427 {
1428         int status = 0;
1429         struct packet *packet;
1430         struct packet *result;
1431
1432         packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1433         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1434                         packet,
1435                         NOTIFICATION_IPC_TIMEOUT);
1436         packet_destroy(packet);
1437
1438         if (result != NULL) {
1439                 if (packet_get(result, "i", &status) != 1) {
1440                         NOTIFICATION_ERR("Failed to get a result packet");
1441                         packet_unref(result);
1442                         return NOTIFICATION_ERROR_IO_ERROR;
1443                 }
1444                 packet_unref(result);
1445         } else {
1446                 NOTIFICATION_ERR("failed to receive answer(refresh)");
1447                 if (notification_ipc_is_master_ready() == 1) {
1448                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1449                 }
1450                 else {
1451                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1452                 }
1453         }
1454
1455         return status;
1456 }
1457
1458
1459 int notification_ipc_update_setting(notification_setting_h setting)
1460 {
1461         int status = 0;
1462         int ret = 0;
1463         struct packet *packet;
1464         struct packet *result;
1465
1466         packet = packet_create("update_noti_setting", "siii", setting->package_name, (int)(setting->allow_to_notify), (int)(setting->do_not_disturb_except), (int)(setting->visibility_class));
1467         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1468                 packet,
1469                 NOTIFICATION_IPC_TIMEOUT);
1470         packet_destroy(packet);
1471
1472         if (result != NULL) {
1473                 if (packet_get(result, "ii", &status, &ret) != 2) {
1474                         NOTIFICATION_ERR("Failed to get a result packet");
1475                         packet_unref(result);
1476                         return NOTIFICATION_ERROR_IO_ERROR;
1477                 }
1478                 packet_unref(result);
1479         } else {
1480                 NOTIFICATION_ERR("failed to receive answer(delete)");
1481                 if (notification_ipc_is_master_ready() == 1) {
1482                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1483                 }
1484                 else {
1485                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1486                 }
1487         }
1488
1489         return status;
1490 }
1491
1492 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1493 {
1494         int status = 0;
1495         int ret = 0;
1496         struct packet *packet = NULL;
1497         struct packet *result = NULL;
1498
1499         packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class));
1500         if (packet == NULL) {
1501                 NOTIFICATION_ERR("packet_create failed.");
1502                 goto out;
1503         }
1504         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT);
1505         packet_destroy(packet);
1506
1507         if (result != NULL) {
1508                 if (packet_get(result, "ii", &status, &ret) != 2) {
1509                         NOTIFICATION_ERR("Failed to get a result packet");
1510                         status = NOTIFICATION_ERROR_IO_ERROR;
1511                         goto out;
1512                 }
1513
1514         } else {
1515                 NOTIFICATION_ERR("failed to receive answer(delete)");
1516                 if (notification_ipc_is_master_ready() == 1) {
1517                         status = NOTIFICATION_ERROR_PERMISSION_DENIED;
1518                         goto out;
1519                 }
1520                 else {
1521                         status = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1522                         goto out;
1523                 }
1524         }
1525 out:
1526         if (result) {
1527                 packet_unref(result);
1528         }
1529
1530         return status;
1531 }
1532
1533 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1534 {
1535         int status = 0;
1536         int ret = 0;
1537         struct packet *packet;
1538         struct packet *result;
1539
1540         packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1541         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1542                         packet,
1543                         NOTIFICATION_IPC_TIMEOUT);
1544         packet_destroy(packet);
1545
1546         if (result != NULL) {
1547                 if (packet_get(result, "ii", &status, &ret) != 2) {
1548                         NOTIFICATION_ERR("Failed to get a result packet");
1549                         packet_unref(result);
1550                         return NOTIFICATION_ERROR_IO_ERROR;
1551                 }
1552                 packet_unref(result);
1553         } else {
1554                 NOTIFICATION_ERR("failed to receive answer(delete)");
1555                 if (notification_ipc_is_master_ready() == 1) {
1556                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1557                 }
1558                 else {
1559                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1560                 }
1561         }
1562
1563         return status;
1564 }
1565
1566 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1567 {
1568         int status = 0;
1569         char *ret = NULL;
1570         struct packet *packet;
1571         struct packet *result;
1572
1573         packet = packet_create("get_noti_property", "ss", pkgname, property);
1574         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1575                         packet,
1576                         NOTIFICATION_IPC_TIMEOUT);
1577         packet_destroy(packet);
1578
1579         if (result != NULL) {
1580                 if (packet_get(result, "is", &status, &ret) != 2) {
1581                         NOTIFICATION_ERR("Failed to get a result packet");
1582                         packet_unref(result);
1583                         return NOTIFICATION_ERROR_IO_ERROR;
1584                 }
1585                 if (status == NOTIFICATION_ERROR_NONE && ret != NULL) {
1586                         *value = strdup(ret);
1587                 }
1588                 packet_unref(result);
1589         } else {
1590                 NOTIFICATION_ERR("failed to receive answer(delete)");
1591                 if (notification_ipc_is_master_ready() == 1) {
1592                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1593                 }
1594                 else {
1595                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1596                 }
1597         }
1598
1599         return status;
1600 }
1601
1602 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1603 {
1604         struct packet *packet;
1605         struct packet *result;
1606
1607         packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1608         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1609                         packet,
1610                         NOTIFICATION_IPC_TIMEOUT);
1611         packet_destroy(packet);
1612
1613         if (result != NULL) {
1614                 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1615                         NOTIFICATION_ERR("Failed to get a result packet");
1616                         packet_unref(result);
1617                         return NOTIFICATION_ERROR_IO_ERROR;
1618                 }
1619
1620                 packet_unref(result);
1621         } else {
1622                 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1623                 if (notification_ipc_is_master_ready() == 1) {
1624                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1625                 }
1626                 else {
1627                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1628                 }
1629         }
1630
1631         return NOTIFICATION_ERROR_NONE;
1632 }
1633