Add changed callback call logic when register service
[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_set_title(notification_h noti,
354                                                        const char *title,
355                                                        const char *loc_title)
356 {
357         int noti_err = NOTIFICATION_ERROR_NONE;
358
359         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
360                                          title, loc_title,
361                                          NOTIFICATION_VARIABLE_TYPE_NONE);
362
363         return noti_err;
364 }
365
366 EXPORT_API int notification_get_title(notification_h noti,
367                                                        char **title,
368                                                        char **loc_title)
369 {
370         int noti_err = NOTIFICATION_ERROR_NONE;
371         char *ret_text = NULL;
372
373         noti_err =
374             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
375                                   &ret_text);
376
377         if (title != NULL)
378                 *title = ret_text;
379
380         if (loc_title != NULL)
381                 *loc_title = NULL;
382
383         return noti_err;
384 }
385
386 EXPORT_API int notification_set_content(notification_h noti,
387                                                          const char *content,
388                                                          const char *loc_content)
389 {
390         int noti_err = NOTIFICATION_ERROR_NONE;
391
392         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
393                                          content, loc_content,
394                                          NOTIFICATION_VARIABLE_TYPE_NONE);
395
396         return noti_err;
397 }
398
399 EXPORT_API int notification_get_content(notification_h noti,
400                                                          char **content,
401                                                          char **loc_content)
402 {
403         int noti_err = NOTIFICATION_ERROR_NONE;
404         char *ret_text = NULL;
405
406         noti_err =
407             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
408                                   &ret_text);
409
410         if (content != NULL)
411                 *content = ret_text;
412
413         if (loc_content != NULL)
414                 *loc_content = NULL;
415
416         return noti_err;
417
418 #if 0
419         ret =
420             vconf_get_bool
421             (VCONFKEY_SETAPPL_STATE_TICKER_NOTI_DISPLAY_CONTENT_BOOL, &boolval);
422
423         if (ret == -1 || boolval == 0) {
424                 if (content != NULL && noti->default_content != NULL)
425                         *content = noti->default_content;
426
427                 if (loc_content != NULL && noti->loc_default_content != NULL)
428                         *loc_content = noti->loc_default_content;
429         }
430 #endif
431 }
432
433 EXPORT_API int notification_set_application(notification_h noti,
434                                                              const char *pkgname)
435 {
436         if (noti == NULL || pkgname == NULL)
437                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
438
439         if (noti->launch_pkgname)
440                 free(noti->launch_pkgname);
441
442         noti->launch_pkgname = strdup(pkgname);
443
444         return NOTIFICATION_ERROR_NONE;
445 }
446
447 EXPORT_API int notification_get_application(notification_h noti,
448                                                              char **pkgname)
449 {
450         if (noti == NULL || pkgname == NULL)
451                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
452
453         if (noti->launch_pkgname)
454                 *pkgname = noti->launch_pkgname;
455         else
456                 *pkgname = noti->caller_pkgname;
457
458         return NOTIFICATION_ERROR_NONE;
459 }
460
461 EXPORT_API int notification_set_args(notification_h noti, bundle *args,
462                 bundle *group_args)
463 {
464         if (noti == NULL || args == NULL)
465                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
466
467         if (noti->args)
468                 bundle_free(noti->args);
469
470         noti->args = bundle_dup(args);
471
472         if (noti->group_args) {
473                 bundle_free(noti->group_args);
474                 noti->group_args = NULL;
475         }
476
477         if (group_args != NULL)
478                 noti->group_args = bundle_dup(group_args);
479
480         return NOTIFICATION_ERROR_NONE;
481 }
482
483 EXPORT_API int notification_get_args(notification_h noti,
484                                                       bundle **args,
485                                                       bundle **group_args)
486 {
487         if (noti == NULL || args == NULL)
488                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
489
490         if (noti->args)
491                 *args = noti->args;
492         else
493                 *args = NULL;
494
495         if (group_args != NULL && noti->group_args)
496                 *group_args = noti->group_args;
497
498         return NOTIFICATION_ERROR_NONE;
499 }
500
501 EXPORT_API int notification_get_grouping_list(notification_type_e type, int count,
502                                notification_list_h *list)
503 {
504         notification_list_h get_list = NULL;
505         int ret = 0;
506
507         if (list == NULL)
508                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
509
510         ret = notification_noti_get_grouping_list(type, count, &get_list);
511         if (ret != NOTIFICATION_ERROR_NONE)
512                 return ret;
513
514         *list = get_list;
515
516         return NOTIFICATION_ERROR_NONE;
517 }
518
519 EXPORT_API int notification_delete_group_by_group_id(const char *pkgname,
520                                                                       notification_type_e type,
521                                                                       int group_id)
522 {
523         int ret = 0;
524         char *caller_pkgname = NULL;
525
526         if (pkgname == NULL)
527                 caller_pkgname = notification_get_pkgname_by_pid();
528         else
529                 caller_pkgname = strdup(pkgname);
530
531         ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
532
533         if (caller_pkgname)
534                 free(caller_pkgname);
535
536         return ret;
537 }
538
539 EXPORT_API int notification_delete_group_by_priv_id(const char *pkgname,
540                                                                      notification_type_e type,
541                                                                      int priv_id)
542 {
543         int ret = 0;
544         char *caller_pkgname = NULL;
545
546         if (pkgname == NULL)
547                 caller_pkgname = notification_get_pkgname_by_pid();
548         else
549                 caller_pkgname = strdup(pkgname);
550
551         ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
552
553         if (caller_pkgname)
554                 free(caller_pkgname);
555
556         return ret;
557 }
558
559 EXPORT_API int notification_get_count(notification_type_e type,
560                                                        const char *pkgname,
561                                                        int group_id,
562                                                        int priv_id, int *count)
563 {
564         int ret = 0;
565         char *caller_pkgname = NULL;
566
567         if (count == NULL)
568                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
569
570         if (pkgname == NULL)
571                 caller_pkgname = notification_get_pkgname_by_pid();
572         else
573                 caller_pkgname = strdup(pkgname);
574
575         ret = notification_ipc_request_get_count(
576                         type,
577                         caller_pkgname,
578                         group_id,
579                         priv_id,
580                         count);
581
582         if (caller_pkgname)
583                 free(caller_pkgname);
584
585         return ret;
586 }
587
588 EXPORT_API int notification_clear(notification_type_e type)
589 {
590         int ret = 0;
591
592         if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX)
593                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
594
595         ret = notification_ipc_request_delete_multiple(type, NULL);
596
597         return ret;
598 }
599
600 EXPORT_API int notification_op_get_data(notification_op *noti_op, notification_op_data_type_e type,
601                                                        void *data)
602 {
603         if (noti_op == NULL || data == NULL)
604                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
605
606         switch (type) {
607         case NOTIFICATION_OP_DATA_TYPE:
608                 *((int *)data) = noti_op->type;
609                 break;
610         case NOTIFICATION_OP_DATA_PRIV_ID:
611                 *((int *)data) = noti_op->priv_id;
612                 break;
613         case NOTIFICATION_OP_DATA_NOTI:
614                 *((notification_h *)data) = noti_op->noti;
615                 break;
616         case NOTIFICATION_OP_DATA_EXTRA_INFO_1:
617                 *((int *)data) = noti_op->extra_info_1;
618                 break;
619         case NOTIFICATION_OP_DATA_EXTRA_INFO_2:
620                 *((int *)data) = noti_op->extra_info_2;
621                 break;
622         default:
623                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
624                 break;
625         }
626
627         return NOTIFICATION_ERROR_NONE;
628 }
629
630 EXPORT_API int notification_set_pkgname(notification_h noti,
631                                                          const char *pkgname)
632 {
633         /* check noti and pkgname are valid data */
634         if (noti == NULL || pkgname == NULL)
635                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
636
637         /* Remove previous caller pkgname */
638         if (noti->caller_pkgname) {
639                 free(noti->caller_pkgname);
640                 noti->caller_pkgname = NULL;
641         }
642
643         noti->caller_pkgname = strdup(pkgname);
644
645         return NOTIFICATION_ERROR_NONE;
646 }
647
648 EXPORT_API int notification_delete_all_by_type(const char *pkgname,
649                                                                 notification_type_e type)
650 {
651         int ret = 0;
652         char *caller_pkgname = NULL;
653
654         if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX)
655                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
656
657         if (pkgname == NULL)
658                 caller_pkgname = notification_get_pkgname_by_pid();
659         else
660                 caller_pkgname = strdup(pkgname);
661
662         ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
663
664         if (caller_pkgname)
665                 free(caller_pkgname);
666
667         return ret;
668 }
669
670 EXPORT_API int notification_delete_by_priv_id(const char *pkgname,
671                                                                notification_type_e type,
672                                                                int priv_id)
673 {
674         int ret = 0;
675         char *caller_pkgname = NULL;
676
677         if (priv_id <= NOTIFICATION_PRIV_ID_NONE)
678                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
679
680         if (pkgname == NULL)
681                 caller_pkgname = notification_get_pkgname_by_pid();
682         else
683                 caller_pkgname = strdup(pkgname);
684
685         ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
686
687         if (caller_pkgname)
688                 free(caller_pkgname);
689
690         return ret;
691 }
692
693 EXPORT_API int notification_set_execute_option(notification_h noti,
694                                                                 notification_execute_type_e type,
695                                                                 const char *text,
696                                                                 const char *key,
697                                                                 bundle *service_handle)
698 {
699         char buf_key[32] = { 0, };
700         char *ret_val = NULL;
701         bundle *b = NULL;
702
703         if (noti == NULL)
704                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
705
706         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
707             || type >= NOTIFICATION_EXECUTE_TYPE_MAX)
708                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
709
710         /* Create execute option bundle if does not exist */
711         if (noti->b_execute_option == NULL)
712                 noti->b_execute_option = bundle_create();
713
714         b = noti->b_execute_option;
715
716         /* Save text */
717         if (text != NULL) {
718                 /* Make text key */
719                 snprintf(buf_key, sizeof(buf_key), "text%d", type);
720
721                 /* Check text key exist */
722                 bundle_get_str(b, buf_key, &ret_val);
723                 if (ret_val != NULL)
724                         /* Remove previous data */
725                         bundle_del(b, buf_key);
726
727                 /* Add text data */
728                 bundle_add_str(b, buf_key, text);
729         }
730
731         /* Save key */
732         if (key != NULL) {
733                 /* Make key key */
734                 snprintf(buf_key, sizeof(buf_key), "key%d", type);
735
736                 /* Check key key exist */
737                 bundle_get_str(b, buf_key, &ret_val);
738                 if (ret_val != NULL)
739                         /* Remove previous data */
740                         bundle_del(b, buf_key);
741
742                 /* Add text data */
743                 bundle_add_str(b, buf_key, key);
744         }
745
746         switch ((int)type) {
747         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
748                 /* Remove previous data if exist */
749                 if (noti->b_service_responding != NULL) {
750                         bundle_free(noti->b_service_responding);
751                         noti->b_service_responding = NULL;
752                 }
753
754                 /* Save service handle */
755                 if (service_handle != NULL)
756                         noti->b_service_responding = bundle_dup(service_handle);
757
758                 break;
759         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
760                 /* Remove previous data if exist */
761                 if (noti->b_service_single_launch != NULL) {
762                         bundle_free(noti->b_service_single_launch);
763                         noti->b_service_single_launch = NULL;
764                 }
765
766                 /* Save service handle */
767                 if (service_handle != NULL)
768                         noti->b_service_single_launch =
769                                 bundle_dup(service_handle);
770
771                 break;
772         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
773                 /* Remove previous data if exist */
774                 if (noti->b_service_multi_launch != NULL) {
775                         bundle_free(noti->b_service_multi_launch);
776                         noti->b_service_multi_launch = NULL;
777                 }
778
779                 /* Save service handle */
780                 if (service_handle != NULL)
781                         noti->b_service_multi_launch =
782                                 bundle_dup(service_handle);
783
784                 break;
785         }
786
787         return NOTIFICATION_ERROR_NONE;
788 }
789
790 EXPORT_API int notification_get_id(notification_h noti,
791                                                     int *group_id, int *priv_id)
792 {
793         /* check noti is valid data */
794         if (noti == NULL)
795                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
796
797         /* Check group_id is valid data */
798         if (group_id) {
799                 /* Set group id */
800                 if (noti->group_id < NOTIFICATION_GROUP_ID_NONE)
801                         *group_id = NOTIFICATION_GROUP_ID_NONE;
802                 else
803                         *group_id = noti->group_id;
804         }
805
806         /* Check priv_id is valid data */
807         if (priv_id)
808                 /* Set priv_id */
809                 *priv_id = noti->priv_id;
810
811         return NOTIFICATION_ERROR_NONE;
812 }
813
814 EXPORT_API notification_h notification_load(char *pkgname,
815                                                       int priv_id)
816 {
817         int ret = 0;
818         notification_h noti = NULL;
819
820         noti = (notification_h)calloc(1, sizeof(struct _notification));
821         if (noti == NULL) {
822                 NOTIFICATION_ERR("NO MEMORY : noti == NULL");
823                 return NULL;
824         }
825
826         ret = notification_ipc_request_load_noti_by_priv_id(noti, pkgname, priv_id);
827         if (ret != NOTIFICATION_ERROR_NONE) {
828                 notification_free(noti);
829                 return NULL;
830         }
831
832         return noti;
833 }
834
835 EXPORT_API notification_h notification_new(notification_type_e type,
836                                            int group_id, int priv_id)
837 {
838         return notification_create(type);
839 }
840
841 static void _notification_get_text_domain(notification_h noti)
842 {
843 /*
844         if (noti->domain != NULL) {
845
846         }
847
848         if (noti->dir != NULL) {
849
850         }
851 */
852 }
853
854 EXPORT_API int notification_get_execute_option(notification_h noti,
855                                                                 notification_execute_type_e type,
856                                                                 const char **text,
857                                                                 bundle **service_handle)
858 {
859         char buf_key[32] = { 0, };
860         char *ret_val = NULL;
861         char *get_str = NULL;
862         bundle *b = NULL;
863
864         if (noti == NULL)
865                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
866
867         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
868             || type >= NOTIFICATION_EXECUTE_TYPE_MAX)
869                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
870
871
872         switch (type) {
873         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
874                 b = noti->b_service_responding;
875                 break;
876         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
877                 b = noti->b_service_single_launch;
878                 break;
879         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
880                 b = noti->b_service_multi_launch;
881                 break;
882         default:
883                 break;
884         }
885
886         if (b != NULL) {
887         /* Return text */
888                 if (text != NULL) {
889                         /*  Get text domain and dir */
890                         if (noti->domain == NULL || noti->dir == NULL)
891                                 _notification_get_text_domain(noti);
892
893                         /* Make key */
894                         snprintf(buf_key, sizeof(buf_key), "key%d", type);
895
896                         /* Check key key exist */
897                         bundle_get_str(b, buf_key, &ret_val);
898                         if (ret_val != NULL && noti->domain != NULL
899                             && noti->dir != NULL) {
900                                 /* Get application string */
901                                 bindtextdomain(noti->domain, noti->dir);
902
903                                 get_str = dgettext(noti->domain, ret_val);
904
905                                 *text = get_str;
906                         } else if (ret_val != NULL) {
907                                 /* Get system string */
908                                 get_str = dgettext("sys_string", ret_val);
909
910                                 *text = get_str;
911                         } else {
912                                 /* Get basic text */
913                                 snprintf(buf_key, sizeof(buf_key), "text%d",
914                                          type);
915
916                                 bundle_get_str(b, buf_key, &ret_val);
917
918                                 *text = ret_val;
919                         }
920                 }
921         }
922
923         if (service_handle != NULL)
924                 *service_handle = b;
925
926         return NOTIFICATION_ERROR_NONE;
927 }
928
929 EXPORT_API int notification_insert(notification_h noti,
930                                                     int *priv_id)
931 {
932         int ret = 0;
933         int id = 0;
934
935         /* Check noti is vaild data */
936         if (noti == NULL)
937                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
938
939         /* Check noti type is valid type */
940         if (noti->type <= NOTIFICATION_TYPE_NONE
941             || noti->type >= NOTIFICATION_TYPE_MAX)
942                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
943
944         /* Save insert time */
945         noti->insert_time = time(NULL);
946         ret = notification_ipc_request_insert(noti, &id);
947         if (ret != NOTIFICATION_ERROR_NONE)
948                 return ret;
949
950         noti->priv_id = id;
951         NOTIFICATION_DBG("from master:%d", id);
952
953         /* If priv_id is valid data, set priv_id */
954         if (priv_id != NULL)
955                 *priv_id = noti->priv_id;
956
957         return NOTIFICATION_ERROR_NONE;
958 }
959
960 EXPORT_API int notification_update_async(notification_h noti,
961                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
962 {
963         int ret = 0;
964
965         if (noti == NULL)
966                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
967
968         /* Update insert time ? */
969         noti->insert_time = time(NULL);
970         ret = notification_ipc_request_update_async(noti, result_cb, user_data);
971
972         return ret;
973 }
974
975 EXPORT_API int notification_register_detailed_changed_cb(
976                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
977                 void *user_data)
978 {
979         notification_cb_list_s *noti_cb_list_new = NULL;
980         notification_cb_list_s *noti_cb_list = NULL;
981
982         if (detailed_changed_cb == NULL)
983                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
984
985         if (notification_ipc_monitor_init() != NOTIFICATION_ERROR_NONE)
986                 return NOTIFICATION_ERROR_IO_ERROR;
987
988         noti_cb_list_new =
989             (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
990
991         if (noti_cb_list_new == NULL) {
992                 NOTIFICATION_ERR("malloc failed");
993                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
994         }
995
996         noti_cb_list_new->next = NULL;
997         noti_cb_list_new->prev = NULL;
998
999         noti_cb_list_new->cb_type = NOTIFICATION_CB_DETAILED;
1000         noti_cb_list_new->changed_cb = NULL;
1001         noti_cb_list_new->detailed_changed_cb = detailed_changed_cb;
1002         noti_cb_list_new->data = user_data;
1003
1004         if (g_notification_cb_list == NULL) {
1005                 g_notification_cb_list = noti_cb_list_new;
1006         } else {
1007                 noti_cb_list = g_notification_cb_list;
1008
1009                 while (noti_cb_list->next != NULL)
1010                         noti_cb_list = noti_cb_list->next;
1011
1012
1013                 noti_cb_list->next = noti_cb_list_new;
1014                 noti_cb_list_new->prev = noti_cb_list;
1015         }
1016         return NOTIFICATION_ERROR_NONE;
1017 }
1018
1019 EXPORT_API int notification_unregister_detailed_changed_cb(
1020                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1021                 void *user_data)
1022 {
1023         notification_cb_list_s *noti_cb_list = NULL;
1024         notification_cb_list_s *noti_cb_list_prev = NULL;
1025         notification_cb_list_s *noti_cb_list_next = NULL;
1026
1027         noti_cb_list = g_notification_cb_list;
1028
1029         if (detailed_changed_cb == NULL)
1030                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1031
1032         if (noti_cb_list == NULL)
1033                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1034
1035
1036         while (noti_cb_list->prev != NULL)
1037                 noti_cb_list = noti_cb_list->prev;
1038
1039
1040         do {
1041                 if (noti_cb_list->detailed_changed_cb == detailed_changed_cb) {
1042                         noti_cb_list_prev = noti_cb_list->prev;
1043                         noti_cb_list_next = noti_cb_list->next;
1044
1045                         if (noti_cb_list_prev == NULL)
1046                                 g_notification_cb_list = noti_cb_list_next;
1047                         else
1048                                 noti_cb_list_prev->next = noti_cb_list_next;
1049
1050                         if (noti_cb_list_next == NULL) {
1051                                 if (noti_cb_list_prev != NULL)
1052                                         noti_cb_list_prev->next = NULL;
1053
1054                         } else {
1055                                 noti_cb_list_next->prev = noti_cb_list_prev;
1056                         }
1057
1058                         free(noti_cb_list);
1059
1060                         if (g_notification_cb_list == NULL)
1061                                 notification_ipc_monitor_fini();
1062
1063                         return NOTIFICATION_ERROR_NONE;
1064                 }
1065                 noti_cb_list = noti_cb_list->next;
1066         } while (noti_cb_list != NULL);
1067
1068         return NOTIFICATION_ERROR_INVALID_PARAMETER;
1069 }
1070
1071 EXPORT_API int notification_is_service_ready(void)
1072 {
1073         return notification_ipc_is_master_ready();
1074 }
1075