Using gdbus for IPC instead of com-core package
[platform/core/api/notification.git] / src / notification_internal.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 <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <libintl.h>
28 #include <dbus/dbus.h>
29 #include <dbus/dbus-glib-lowlevel.h>
30
31 #include <app.h>
32 #include <app_control_internal.h>
33 #include <aul.h>
34 #include <ail.h>
35 #include <appsvc.h>
36 #include <tizen.h>
37 #include <vconf-keys.h>
38 #include <vconf.h>
39
40 #include <notification.h>
41 #include <notification_list.h>
42 #include <notification_debug.h>
43 #include <notification_private.h>
44 #include <notification_noti.h>
45 #include <notification_ongoing.h>
46 #include <notification_group.h>
47 #include <notification_ipc.h>
48 #include <notification_internal.h>
49
50 typedef struct _notification_cb_list notification_cb_list_s;
51
52 typedef enum __notification_cb_type {
53         NOTIFICATION_CB_NORMAL = 1,
54         NOTIFICATION_CB_DETAILED,
55 } _notification_cb_type_e;
56
57 struct _notification_cb_list {
58         notification_cb_list_s *prev;
59         notification_cb_list_s *next;
60
61         _notification_cb_type_e cb_type;
62         void (*changed_cb) (void *data, notification_type_e type);
63         void (*detailed_changed_cb) (void *data, notification_type_e type, notification_op *op_list, int num_op);
64         void *data;
65 };
66
67 static notification_cb_list_s *g_notification_cb_list = NULL;
68
69 void notification_call_changed_cb(notification_op *op_list, int op_num)
70 {
71         notification_cb_list_s *noti_cb_list = NULL;
72         notification_type_e type = 0;
73
74         if (g_notification_cb_list == NULL)
75                 return;
76
77         noti_cb_list = g_notification_cb_list;
78
79         while (noti_cb_list->prev != NULL)
80                 noti_cb_list = noti_cb_list->prev;
81
82
83         if (op_list == NULL) {
84                 NOTIFICATION_ERR("invalid data");
85                 return ;
86         }
87
88         notification_get_type(op_list->noti, &type);
89
90         while (noti_cb_list != NULL) {
91                 if (noti_cb_list->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_list->changed_cb) {
92                         noti_cb_list->changed_cb(noti_cb_list->data,
93                                                  type);
94                 }
95                 if (noti_cb_list->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_list->detailed_changed_cb) {
96                         noti_cb_list->detailed_changed_cb(noti_cb_list->data,
97                                                 type, op_list, op_num);
98                 }
99
100                 noti_cb_list = noti_cb_list->next;
101         }
102 }
103
104 EXPORT_API int notification_add_deferred_task(
105                 void (*deferred_task_cb)(void *data), void *user_data)
106 {
107         if (deferred_task_cb == NULL)
108                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
109
110         return notification_ipc_add_deffered_task(deferred_task_cb, user_data);
111 }
112
113 EXPORT_API int notification_del_deferred_task(
114                 void (*deferred_task_cb)(void *data))
115 {
116         if (deferred_task_cb == NULL)
117                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
118
119         return notification_ipc_del_deffered_task(deferred_task_cb);
120 }
121
122 EXPORT_API int notification_resister_changed_cb(void (*changed_cb)
123                                  (void *data, notification_type_e type),
124                                  void *user_data)
125 {
126         notification_cb_list_s *noti_cb_list_new = NULL;
127         notification_cb_list_s *noti_cb_list = NULL;
128
129         if (changed_cb == NULL)
130                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
131
132         if (notification_ipc_monitor_init() != NOTIFICATION_ERROR_NONE)
133                 return NOTIFICATION_ERROR_IO_ERROR;
134
135         noti_cb_list_new =
136             (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
137
138         if (noti_cb_list_new == NULL) {
139                 NOTIFICATION_ERR("malloc failed");
140                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
141         }
142
143         noti_cb_list_new->next = NULL;
144         noti_cb_list_new->prev = NULL;
145
146         noti_cb_list_new->cb_type = NOTIFICATION_CB_NORMAL;
147         noti_cb_list_new->changed_cb = changed_cb;
148         noti_cb_list_new->detailed_changed_cb = NULL;
149         noti_cb_list_new->data = user_data;
150
151         if (g_notification_cb_list == NULL) {
152                 g_notification_cb_list = noti_cb_list_new;
153         } else {
154                 noti_cb_list = g_notification_cb_list;
155
156                 while (noti_cb_list->next != NULL)
157                         noti_cb_list = noti_cb_list->next;
158
159
160                 noti_cb_list->next = noti_cb_list_new;
161                 noti_cb_list_new->prev = noti_cb_list;
162         }
163         return NOTIFICATION_ERROR_NONE;
164 }
165
166 EXPORT_API int notification_unresister_changed_cb(void (*changed_cb)
167                                    (void *data, notification_type_e type))
168 {
169         notification_cb_list_s *noti_cb_list = NULL;
170         notification_cb_list_s *noti_cb_list_prev = NULL;
171         notification_cb_list_s *noti_cb_list_next = NULL;
172
173         noti_cb_list = g_notification_cb_list;
174
175         if (changed_cb == NULL)
176                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
177
178         if (noti_cb_list == NULL)
179                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
180
181         while (noti_cb_list->prev != NULL)
182                 noti_cb_list = noti_cb_list->prev;
183
184
185         do {
186                 if (noti_cb_list->changed_cb == changed_cb) {
187                         noti_cb_list_prev = noti_cb_list->prev;
188                         noti_cb_list_next = noti_cb_list->next;
189
190                         if (noti_cb_list_prev == NULL)
191                                 g_notification_cb_list = noti_cb_list_next;
192                         else
193                                 noti_cb_list_prev->next = noti_cb_list_next;
194
195                         if (noti_cb_list_next == NULL) {
196                                 if (noti_cb_list_prev != NULL)
197                                         noti_cb_list_prev->next = NULL;
198
199                         } else {
200                                 noti_cb_list_next->prev = noti_cb_list_prev;
201                         }
202
203                         free(noti_cb_list);
204
205                         if (g_notification_cb_list == NULL)
206                                 notification_ipc_monitor_fini();
207
208                         return NOTIFICATION_ERROR_NONE;
209                 }
210                 noti_cb_list = noti_cb_list->next;
211         } while (noti_cb_list != NULL);
212
213         return NOTIFICATION_ERROR_INVALID_PARAMETER;
214 }
215
216 EXPORT_API int notification_update_progress(notification_h noti,
217                                                              int priv_id,
218                                                              double progress)
219 {
220         char *caller_pkgname = NULL;
221         int input_priv_id = 0;
222         int ret = 0;
223         double input_progress = 0.0;
224
225         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
226                 if (noti == NULL)
227                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
228                 else
229                         input_priv_id = noti->priv_id;
230
231         } else {
232                 input_priv_id = priv_id;
233         }
234
235         if (noti == NULL)
236                 caller_pkgname = notification_get_pkgname_by_pid();
237         else
238                 caller_pkgname = strdup(noti->caller_pkgname);
239
240         if (progress < 0.0)
241                 input_progress = 0.0;
242         else if (progress > 1.0)
243                 input_progress = 1.0;
244         else
245                 input_progress = progress;
246
247         ret = notification_ongoing_update_progress(caller_pkgname, input_priv_id,
248                                              input_progress);
249
250         if (caller_pkgname)
251                 free(caller_pkgname);
252
253         return ret;
254 }
255
256 EXPORT_API int notification_update_size(notification_h noti,
257                                                          int priv_id,
258                                                          double size)
259 {
260         char *caller_pkgname = NULL;
261         int input_priv_id = 0;
262         int ret = 0;
263         double input_size = 0.0;
264
265         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
266                 if (noti == NULL)
267                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
268                 else
269                         input_priv_id = noti->priv_id;
270         } else {
271                 input_priv_id = priv_id;
272         }
273
274         if (noti == NULL)
275                 caller_pkgname = notification_get_pkgname_by_pid();
276         else
277                 caller_pkgname = strdup(noti->caller_pkgname);
278
279         if (size < 0.0)
280                 input_size = 0.0;
281         else
282                 input_size = size;
283
284         ret = notification_ongoing_update_size(caller_pkgname, input_priv_id,
285                                          input_size);
286
287         if (caller_pkgname)
288                 free(caller_pkgname);
289
290         return ret;
291 }
292
293 EXPORT_API int notification_update_content(notification_h noti,
294                                                          int priv_id,
295                                                          const char *content)
296 {
297         char *caller_pkgname = NULL;
298         int input_priv_id = 0;
299         int ret = 0;
300
301         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
302                 if (noti == NULL)
303                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
304                 else
305                         input_priv_id = noti->priv_id;
306
307         } else {
308                 input_priv_id = priv_id;
309         }
310
311         if (noti == NULL)
312                 caller_pkgname = notification_get_pkgname_by_pid();
313         else
314                 caller_pkgname = strdup(noti->caller_pkgname);
315
316         ret = notification_ongoing_update_content(caller_pkgname, input_priv_id,
317                                          content);
318
319         if (caller_pkgname)
320                 free(caller_pkgname);
321
322         return ret;
323 }
324
325 /* notification_set_icon will be removed */
326 EXPORT_API int notification_set_icon(notification_h noti,
327                                                       const char *icon_path)
328 {
329         int ret_err = NOTIFICATION_ERROR_NONE;
330
331         ret_err =
332             notification_set_image(noti, NOTIFICATION_IMAGE_TYPE_ICON,
333                                    icon_path);
334
335         return ret_err;
336 }
337
338 /* notification_get_icon will be removed */
339 EXPORT_API int notification_get_icon(notification_h noti,
340                                                       char **icon_path)
341 {
342         int ret_err = NOTIFICATION_ERROR_NONE;
343         char *ret_image_path = NULL;
344
345         ret_err =
346             notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON,
347                                    &ret_image_path);
348
349         if (ret_err == NOTIFICATION_ERROR_NONE && icon_path != NULL)
350                 *icon_path = ret_image_path;
351
352         return ret_err;
353 }
354
355 EXPORT_API int notification_set_title(notification_h noti,
356                                                        const char *title,
357                                                        const char *loc_title)
358 {
359         int noti_err = NOTIFICATION_ERROR_NONE;
360
361         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
362                                          title, loc_title,
363                                          NOTIFICATION_VARIABLE_TYPE_NONE);
364
365         return noti_err;
366 }
367
368 EXPORT_API int notification_get_title(notification_h noti,
369                                                        char **title,
370                                                        char **loc_title)
371 {
372         int noti_err = NOTIFICATION_ERROR_NONE;
373         char *ret_text = NULL;
374
375         noti_err =
376             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
377                                   &ret_text);
378
379         if (title != NULL)
380                 *title = ret_text;
381
382         if (loc_title != NULL)
383                 *loc_title = NULL;
384
385         return noti_err;
386 }
387
388 EXPORT_API int notification_set_content(notification_h noti,
389                                                          const char *content,
390                                                          const char *loc_content)
391 {
392         int noti_err = NOTIFICATION_ERROR_NONE;
393
394         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
395                                          content, loc_content,
396                                          NOTIFICATION_VARIABLE_TYPE_NONE);
397
398         return noti_err;
399 }
400
401 EXPORT_API int notification_get_content(notification_h noti,
402                                                          char **content,
403                                                          char **loc_content)
404 {
405         int noti_err = NOTIFICATION_ERROR_NONE;
406         char *ret_text = NULL;
407
408         noti_err =
409             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
410                                   &ret_text);
411
412         if (content != NULL)
413                 *content = ret_text;
414
415         if (loc_content != NULL)
416                 *loc_content = NULL;
417
418         return noti_err;
419
420 #if 0
421         ret =
422             vconf_get_bool
423             (VCONFKEY_SETAPPL_STATE_TICKER_NOTI_DISPLAY_CONTENT_BOOL, &boolval);
424
425         if (ret == -1 || boolval == 0) {
426                 if (content != NULL && noti->default_content != NULL)
427                         *content = noti->default_content;
428
429                 if (loc_content != NULL && noti->loc_default_content != NULL)
430                         *loc_content = noti->loc_default_content;
431         }
432 #endif
433 }
434
435 EXPORT_API int notification_set_application(notification_h noti,
436                                                              const char *pkgname)
437 {
438         if (noti == NULL || pkgname == NULL)
439                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
440
441         if (noti->launch_pkgname)
442                 free(noti->launch_pkgname);
443
444         noti->launch_pkgname = strdup(pkgname);
445
446         return NOTIFICATION_ERROR_NONE;
447 }
448
449 EXPORT_API int notification_get_application(notification_h noti,
450                                                              char **pkgname)
451 {
452         if (noti == NULL || pkgname == NULL)
453                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
454
455         if (noti->launch_pkgname)
456                 *pkgname = noti->launch_pkgname;
457         else
458                 *pkgname = noti->caller_pkgname;
459
460         return NOTIFICATION_ERROR_NONE;
461 }
462
463 EXPORT_API int notification_set_args(notification_h noti,
464                                                       bundle * args,
465                                                       bundle * group_args)
466 {
467         if (noti == NULL || args == NULL)
468                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
469
470         if (noti->args)
471                 bundle_free(noti->args);
472
473         noti->args = bundle_dup(args);
474
475         if (noti->group_args) {
476                 bundle_free(noti->group_args);
477                 noti->group_args = NULL;
478         }
479
480         if (group_args != NULL)
481                 noti->group_args = bundle_dup(group_args);
482
483         return NOTIFICATION_ERROR_NONE;
484 }
485
486 EXPORT_API int notification_get_args(notification_h noti,
487                                                       bundle ** args,
488                                                       bundle ** group_args)
489 {
490         if (noti == NULL || args == NULL)
491                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
492
493         if (noti->args)
494                 *args = noti->args;
495         else
496                 *args = NULL;
497
498         if (group_args != NULL && noti->group_args)
499                 *group_args = noti->group_args;
500
501         return NOTIFICATION_ERROR_NONE;
502 }
503
504 EXPORT_API int notification_get_grouping_list(notification_type_e type, int count,
505                                notification_list_h * list)
506 {
507         notification_list_h get_list = NULL;
508         int ret = 0;
509
510         if (list == NULL)
511                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
512
513         ret = notification_noti_get_grouping_list(type, count, &get_list);
514         if (ret != NOTIFICATION_ERROR_NONE)
515                 return ret;
516
517         *list = get_list;
518
519         return NOTIFICATION_ERROR_NONE;
520 }
521
522 EXPORT_API int notification_delete_group_by_group_id(const char *pkgname,
523                                                                       notification_type_e type,
524                                                                       int group_id)
525 {
526         int ret = 0;
527         char *caller_pkgname = NULL;
528
529         if (pkgname == NULL)
530                 caller_pkgname = notification_get_pkgname_by_pid();
531         else
532                 caller_pkgname = strdup(pkgname);
533
534         ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
535
536         if (caller_pkgname)
537                 free(caller_pkgname);
538
539         return ret;
540 }
541
542 EXPORT_API int notification_delete_group_by_priv_id(const char *pkgname,
543                                                                      notification_type_e type,
544                                                                      int priv_id)
545 {
546         int ret = 0;
547         char *caller_pkgname = NULL;
548
549         if (pkgname == NULL)
550                 caller_pkgname = notification_get_pkgname_by_pid();
551         else
552                 caller_pkgname = strdup(pkgname);
553
554         ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
555
556         if (caller_pkgname)
557                 free(caller_pkgname);
558
559         return ret;
560 }
561
562 EXPORT_API int notification_get_count(notification_type_e type,
563                                                        const char *pkgname,
564                                                        int group_id,
565                                                        int priv_id, int *count)
566 {
567         int ret = 0;
568         char *caller_pkgname = NULL;
569
570         if (count == NULL)
571                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
572
573         if (pkgname == NULL)
574                 caller_pkgname = notification_get_pkgname_by_pid();
575         else
576                 caller_pkgname = strdup(pkgname);
577
578         ret = notification_ipc_request_get_count(
579                         type,
580                         caller_pkgname,
581                         group_id,
582                         priv_id,
583                         count);
584
585         if (caller_pkgname)
586                 free(caller_pkgname);
587
588         return ret;
589 }
590
591 EXPORT_API int notification_clear(notification_type_e type)
592 {
593         int ret = 0;
594
595         if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX)
596                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
597
598         ret = notification_ipc_request_delete_multiple(type, NULL);
599
600         return ret;
601 }
602
603 EXPORT_API int notification_op_get_data(notification_op *noti_op, notification_op_data_type_e type,
604                                                        void *data)
605 {
606         if (noti_op == NULL || data == NULL)
607                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
608
609         switch (type) {
610         case NOTIFICATION_OP_DATA_TYPE:
611                 *((int*)data) = noti_op->type;
612                 break;
613         case NOTIFICATION_OP_DATA_PRIV_ID:
614                 *((int*)data) = noti_op->priv_id;
615                 break;
616         case NOTIFICATION_OP_DATA_NOTI:
617                 *((notification_h *)data) = noti_op->noti;
618                 break;
619         case NOTIFICATION_OP_DATA_EXTRA_INFO_1:
620                 *((int*)data) = noti_op->extra_info_1;
621                 break;
622         case NOTIFICATION_OP_DATA_EXTRA_INFO_2:
623                 *((int*)data) = noti_op->extra_info_2;
624                 break;
625         default:
626                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
627                 break;
628         }
629
630         return NOTIFICATION_ERROR_NONE;
631 }
632
633 EXPORT_API int notification_set_pkgname(notification_h noti,
634                                                          const char *pkgname)
635 {
636         /* check noti and pkgname are valid data */
637         if (noti == NULL || pkgname == NULL)
638                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
639
640         /* Remove previous caller pkgname */
641         if (noti->caller_pkgname) {
642                 free(noti->caller_pkgname);
643                 noti->caller_pkgname = NULL;
644         }
645
646         noti->caller_pkgname = strdup(pkgname);
647
648         return NOTIFICATION_ERROR_NONE;
649 }
650
651 EXPORT_API int notification_delete_all_by_type(const char *pkgname,
652                                                                 notification_type_e type)
653 {
654         int ret = 0;
655         char *caller_pkgname = NULL;
656
657         if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX)
658                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
659
660         if (pkgname == NULL)
661                 caller_pkgname = notification_get_pkgname_by_pid();
662         else
663                 caller_pkgname = strdup(pkgname);
664
665         ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
666
667         if (caller_pkgname)
668                 free(caller_pkgname);
669
670         return ret;
671 }
672
673 EXPORT_API int notification_delete_by_priv_id(const char *pkgname,
674                                                                notification_type_e type,
675                                                                int priv_id)
676 {
677         int ret = 0;
678         char *caller_pkgname = NULL;
679
680         if (priv_id <= NOTIFICATION_PRIV_ID_NONE)
681                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
682
683         if (pkgname == NULL)
684                 caller_pkgname = notification_get_pkgname_by_pid();
685         else
686                 caller_pkgname = strdup(pkgname);
687
688         ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
689
690         if (caller_pkgname)
691                 free(caller_pkgname);
692
693         return ret;
694 }
695
696 EXPORT_API int notification_set_execute_option(notification_h noti,
697                                                                 notification_execute_type_e type,
698                                                                 const char *text,
699                                                                 const char *key,
700                                                                 bundle *service_handle)
701 {
702         char buf_key[32] = { 0, };
703         char *ret_val = NULL;
704         bundle *b = NULL;
705
706         if (noti == NULL)
707                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
708
709         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
710             || type >= NOTIFICATION_EXECUTE_TYPE_MAX)
711                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
712
713         /* Create execute option bundle if does not exist */
714         if (noti->b_execute_option == NULL)
715                 noti->b_execute_option = bundle_create();
716
717         b = noti->b_execute_option;
718
719         /* Save text */
720         if (text != NULL) {
721                 /* Make text key */
722                 snprintf(buf_key, sizeof(buf_key), "text%d", type);
723
724                 /* Check text key exist */
725                 bundle_get_str(b, buf_key, &ret_val);
726                 if (ret_val != NULL)
727                         /* Remove previous data */
728                         bundle_del(b, buf_key);
729
730                 /* Add text data */
731                 bundle_add_str(b, buf_key, text);
732         }
733
734         /* Save key */
735         if (key != NULL) {
736                 /* Make key key */
737                 snprintf(buf_key, sizeof(buf_key), "key%d", type);
738
739                 /* Check key key exist */
740                 bundle_get_str(b, buf_key, &ret_val);
741                 if (ret_val != NULL)
742                         /* Remove previous data */
743                         bundle_del(b, buf_key);
744
745                 /* Add text data */
746                 bundle_add_str(b, buf_key, key);
747         }
748
749         switch ((int)type) {
750         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
751                 /* Remove previous data if exist */
752                 if (noti->b_service_responding != NULL) {
753                         bundle_free(noti->b_service_responding);
754                         noti->b_service_responding = NULL;
755                 }
756
757                 /* Save service handle */
758                 if (service_handle != NULL)
759                         noti->b_service_responding = bundle_dup(service_handle);
760
761                 break;
762         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
763                 /* Remove previous data if exist */
764                 if (noti->b_service_single_launch != NULL) {
765                         bundle_free(noti->b_service_single_launch);
766                         noti->b_service_single_launch = NULL;
767                 }
768
769                 /* Save service handle */
770                 if (service_handle != NULL)
771                         noti->b_service_single_launch =
772                                 bundle_dup(service_handle);
773
774                 break;
775         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
776                 /* Remove previous data if exist */
777                 if (noti->b_service_multi_launch != NULL) {
778                         bundle_free(noti->b_service_multi_launch);
779                         noti->b_service_multi_launch = NULL;
780                 }
781
782                 /* Save service handle */
783                 if (service_handle != NULL)
784                         noti->b_service_multi_launch =
785                                 bundle_dup(service_handle);
786
787                 break;
788         }
789
790         return NOTIFICATION_ERROR_NONE;
791 }
792
793 EXPORT_API int notification_get_id(notification_h noti,
794                                                     int *group_id, int *priv_id)
795 {
796         /* check noti is valid data */
797         if (noti == NULL)
798                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
799
800         /* Check group_id is valid data */
801         if (group_id) {
802                 /* Set group id */
803                 if (noti->group_id < NOTIFICATION_GROUP_ID_NONE)
804                         *group_id = NOTIFICATION_GROUP_ID_NONE;
805                 else
806                         *group_id = noti->group_id;
807         }
808
809         /* Check priv_id is valid data */
810         if (priv_id)
811                 /* Set priv_id */
812                 *priv_id = noti->priv_id;
813
814         return NOTIFICATION_ERROR_NONE;
815 }
816
817 EXPORT_API notification_h notification_load(char *pkgname,
818                                                       int priv_id)
819 {
820         int ret = 0;
821         notification_h noti = NULL;
822
823         noti = (notification_h)calloc(1, sizeof(struct _notification));
824         if (noti == NULL) {
825                 NOTIFICATION_ERR("NO MEMORY : noti == NULL");
826                 return NULL;
827         }
828
829         ret = notification_ipc_request_load_noti_by_priv_id(noti, pkgname, priv_id);
830         if (ret != NOTIFICATION_ERROR_NONE) {
831                 notification_free(noti);
832                 return NULL;
833         }
834
835         return noti;
836 }
837
838 EXPORT_API notification_h notification_new(notification_type_e type,
839                                            int group_id, int priv_id)
840 {
841         return notification_create(type);
842 }
843
844 static void _notification_get_text_domain(notification_h noti)
845 {
846 /*
847         if (noti->domain != NULL) {
848
849         }
850
851         if (noti->dir != NULL) {
852
853         }
854 */
855 }
856
857 EXPORT_API int notification_get_execute_option(notification_h noti,
858                                                                 notification_execute_type_e type,
859                                                                 const char **text,
860                                                                 bundle **service_handle)
861 {
862         char buf_key[32] = { 0, };
863         char *ret_val = NULL;
864         char *get_str = NULL;
865         bundle *b = NULL;
866
867         if (noti == NULL)
868                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
869
870         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
871             || type >= NOTIFICATION_EXECUTE_TYPE_MAX)
872                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
873
874
875         switch (type) {
876         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
877                 b = noti->b_service_responding;
878                 break;
879         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
880                 b = noti->b_service_single_launch;
881                 break;
882         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
883                 b = noti->b_service_multi_launch;
884                 break;
885         default:
886                 break;
887         }
888
889         if (b != NULL) {
890         /* Return text */
891                 if (text != NULL) {
892                         /*  Get text domain and dir */
893                         if (noti->domain == NULL || noti->dir == NULL)
894                                 _notification_get_text_domain(noti);
895
896                         /* Make key */
897                         snprintf(buf_key, sizeof(buf_key), "key%d", type);
898
899                         /* Check key key exist */
900                         bundle_get_str(b, buf_key, &ret_val);
901                         if (ret_val != NULL && noti->domain != NULL
902                             && noti->dir != NULL) {
903                                 /* Get application string */
904                                 bindtextdomain(noti->domain, noti->dir);
905
906                                 get_str = dgettext(noti->domain, ret_val);
907
908                                 *text = get_str;
909                         } else if (ret_val != NULL) {
910                                 /* Get system string */
911                                 get_str = dgettext("sys_string", ret_val);
912
913                                 *text = get_str;
914                         } else {
915                                 /* Get basic text */
916                                 snprintf(buf_key, sizeof(buf_key), "text%d",
917                                          type);
918
919                                 bundle_get_str(b, buf_key, &ret_val);
920
921                                 *text = ret_val;
922                         }
923                 }
924         }
925
926         if (service_handle != NULL)
927                 *service_handle = b;
928
929         return NOTIFICATION_ERROR_NONE;
930 }
931
932 EXPORT_API int notification_insert(notification_h noti,
933                                                     int *priv_id)
934 {
935         int ret = 0;
936         int id = 0;
937
938         /* Check noti is vaild data */
939         if (noti == NULL)
940                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
941
942         /* Check noti type is valid type */
943         if (noti->type <= NOTIFICATION_TYPE_NONE
944             || noti->type >= NOTIFICATION_TYPE_MAX)
945                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
946
947         /* Save insert time */
948         noti->insert_time = time(NULL);
949         ret = notification_ipc_request_insert(noti, &id);
950         if (ret != NOTIFICATION_ERROR_NONE)
951                 return ret;
952
953         noti->priv_id = id;
954         NOTIFICATION_DBG("from master:%d", id);
955
956         /* If priv_id is valid data, set priv_id */
957         if (priv_id != NULL)
958                 *priv_id = noti->priv_id;
959
960         return NOTIFICATION_ERROR_NONE;
961 }
962
963 EXPORT_API int notification_update_async(notification_h noti,
964                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
965 {
966         int ret = 0;
967
968         if (noti == NULL)
969                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
970
971         /* Update insert time ? */
972         noti->insert_time = time(NULL);
973         ret = notification_ipc_request_update_async(noti, result_cb, user_data);
974
975         return ret;
976 }
977
978 EXPORT_API int notification_register_detailed_changed_cb(
979                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
980                 void *user_data)
981 {
982         notification_cb_list_s *noti_cb_list_new = NULL;
983         notification_cb_list_s *noti_cb_list = NULL;
984
985         if (detailed_changed_cb == NULL)
986                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
987
988         if (notification_ipc_monitor_init() != NOTIFICATION_ERROR_NONE)
989                 return NOTIFICATION_ERROR_IO_ERROR;
990
991         noti_cb_list_new =
992             (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
993
994         if (noti_cb_list_new == NULL) {
995                 NOTIFICATION_ERR("malloc failed");
996                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
997         }
998
999         noti_cb_list_new->next = NULL;
1000         noti_cb_list_new->prev = NULL;
1001
1002         noti_cb_list_new->cb_type = NOTIFICATION_CB_DETAILED;
1003         noti_cb_list_new->changed_cb = NULL;
1004         noti_cb_list_new->detailed_changed_cb = detailed_changed_cb;
1005         noti_cb_list_new->data = user_data;
1006
1007         if (g_notification_cb_list == NULL) {
1008                 g_notification_cb_list = noti_cb_list_new;
1009         } else {
1010                 noti_cb_list = g_notification_cb_list;
1011
1012                 while (noti_cb_list->next != NULL)
1013                         noti_cb_list = noti_cb_list->next;
1014
1015
1016                 noti_cb_list->next = noti_cb_list_new;
1017                 noti_cb_list_new->prev = noti_cb_list;
1018         }
1019         return NOTIFICATION_ERROR_NONE;
1020 }
1021
1022 EXPORT_API int notification_unregister_detailed_changed_cb(
1023                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1024                 void *user_data)
1025 {
1026         notification_cb_list_s *noti_cb_list = NULL;
1027         notification_cb_list_s *noti_cb_list_prev = NULL;
1028         notification_cb_list_s *noti_cb_list_next = NULL;
1029
1030         noti_cb_list = g_notification_cb_list;
1031
1032         if (detailed_changed_cb == NULL)
1033                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1034
1035         if (noti_cb_list == NULL)
1036                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1037
1038
1039         while (noti_cb_list->prev != NULL)
1040                 noti_cb_list = noti_cb_list->prev;
1041
1042
1043         do {
1044                 if (noti_cb_list->detailed_changed_cb == detailed_changed_cb) {
1045                         noti_cb_list_prev = noti_cb_list->prev;
1046                         noti_cb_list_next = noti_cb_list->next;
1047
1048                         if (noti_cb_list_prev == NULL)
1049                                 g_notification_cb_list = noti_cb_list_next;
1050                         else
1051                                 noti_cb_list_prev->next = noti_cb_list_next;
1052
1053                         if (noti_cb_list_next == NULL) {
1054                                 if (noti_cb_list_prev != NULL)
1055                                         noti_cb_list_prev->next = NULL;
1056
1057                         } else {
1058                                 noti_cb_list_next->prev = noti_cb_list_prev;
1059                         }
1060
1061                         free(noti_cb_list);
1062
1063                         if (g_notification_cb_list == NULL)
1064                                 notification_ipc_monitor_fini();
1065
1066                         return NOTIFICATION_ERROR_NONE;
1067                 }
1068                 noti_cb_list = noti_cb_list->next;
1069         } while (noti_cb_list != NULL);
1070
1071         return NOTIFICATION_ERROR_INVALID_PARAMETER;
1072 }
1073
1074 EXPORT_API int notification_is_service_ready(void)
1075 {
1076         return notification_ipc_is_master_ready();
1077 }