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