Release notification lib for Tizen2.0 beta(tagging)
[apps/home/notification.git] / src / notification.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>, Youngsub Ko <ys4610.ko@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 <aul.h>
32 #include <ail.h>
33 #include <appsvc.h>
34 #include <vconf-keys.h>
35 #include <vconf.h>
36
37 #include <notification.h>
38 #include <notification_list.h>
39 #include <notification_debug.h>
40 #include <notification_internal.h>
41 #include <notification_noti.h>
42 #include <notification_ongoing.h>
43 #include <notification_group.h>
44
45 typedef struct _notification_cb_list notification_cb_list_s;
46
47 struct _notification_cb_list {
48         notification_cb_list_s *prev;
49         notification_cb_list_s *next;
50
51         void (*changed_cb) (void *data, notification_type_e type);
52         void *data;
53 };
54
55 static notification_cb_list_s *g_notification_cb_list = NULL;
56 static DBusConnection *g_dbus_handle;
57
58 #define NOTI_PKGNAME_LEN        512
59 #define NOTI_CHANGED_NOTI       "notification_noti_changed"
60 #define NOTI_CHANGED_ONGOING    "notification_ontoing_changed"
61
62 #define NOTI_DBUS_BUS_NAME      "org.tizen.libnotification"
63 #define NOTI_DBUS_PATH          "/org/tizen/libnotification"
64 #define NOTI_DBUS_INTERFACE     "org.tizen.libnotification.signal"
65
66 static char *_notification_get_pkgname_by_pid(void)
67 {
68         char buf[NOTI_PKGNAME_LEN] = { 0, };
69         char pkgname[NOTI_PKGNAME_LEN] = { 0, };
70         int pid = 0, ret = AUL_R_OK;
71         int fd;
72
73         pid = getpid();
74
75         ret = aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname));
76         if (ret != AUL_R_OK) {
77                 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
78
79                 fd = open(buf, O_RDONLY);
80                 if (fd < 0) {
81                         return NULL;
82                 }
83
84                 ret = read(fd, pkgname, sizeof(pkgname) - 1);
85                 if (ret <= 0) {
86                         close(fd);
87                         return NULL;
88                 }
89
90                 buf[ret] = 0;
91
92                 close(fd);
93         }
94
95         if (pkgname == NULL || pkgname[0] == '\0') {
96                 return NULL;
97         } else {
98                 return strdup(pkgname);
99         }
100 }
101
102 static char *_notification_get_icon(const char *package)
103 {
104         ail_appinfo_h handle;
105         ail_error_e ret;
106         char *str = NULL;
107         char *icon = NULL;
108
109         ret = ail_package_get_appinfo(package, &handle);
110         if (ret != AIL_ERROR_OK) {
111                 return NULL;
112         }
113
114         ret = ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &str);
115         if (ret != AIL_ERROR_OK) {
116                 ail_package_destroy_appinfo(handle);
117                 return NULL;
118         }
119
120         icon = strdup(str);
121
122         ret = ail_package_destroy_appinfo(handle);
123         if (ret != AIL_ERROR_OK) {
124                 NOTIFICATION_ERR("Fail to ail_package_destroy_appinfo");
125         }
126
127         return icon;
128 }
129
130 static char *_notification_get_name(const char *package)
131 {
132         ail_appinfo_h handle;
133         ail_error_e ret;
134         char *str = NULL;
135         char *name = NULL;
136
137         ret = ail_package_get_appinfo(package, &handle);
138         if (ret != AIL_ERROR_OK) {
139                 return NULL;
140         }
141
142         ret = ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str);
143         if (ret != AIL_ERROR_OK) {
144                 ail_package_destroy_appinfo(handle);
145                 return NULL;
146         }
147
148         name = strdup(str);
149
150         ret = ail_package_destroy_appinfo(handle);
151         if (ret != AIL_ERROR_OK) {
152                 NOTIFICATION_ERR("Fail to ail_package_destroy_appinfo");
153         }
154
155         return name;
156 }
157
158 static void _notification_get_text_domain(notification_h noti)
159 {
160         if (noti->domain != NULL) {
161
162         }
163
164         if (noti->dir != NULL) {
165
166         }
167 }
168
169 static void _notification_chagned_noti_cb(void *data)
170 {
171         notification_cb_list_s *noti_cb_list = NULL;
172
173         if (g_notification_cb_list == NULL) {
174                 return;
175         }
176
177         noti_cb_list = g_notification_cb_list;
178
179         while (noti_cb_list->prev != NULL) {
180                 noti_cb_list = noti_cb_list->prev;
181         }
182
183         while (noti_cb_list != NULL) {
184                 if (noti_cb_list->changed_cb) {
185                         noti_cb_list->changed_cb(noti_cb_list->data,
186                                                  NOTIFICATION_TYPE_NOTI);
187                 }
188
189                 noti_cb_list = noti_cb_list->next;
190         }
191 }
192
193 #if 0
194 static void _notification_chagned_ongoing_cb(void *data)
195 {
196         notification_cb_list_s *noti_cb_list = NULL;
197
198         if (g_notification_cb_list == NULL) {
199                 return;
200         }
201
202         noti_cb_list = g_notification_cb_list;
203
204         while (noti_cb_list->prev != NULL) {
205                 noti_cb_list = noti_cb_list->prev;
206         }
207
208         while (noti_cb_list != NULL) {
209                 if (noti_cb_list->changed_cb) {
210                         noti_cb_list->changed_cb(noti_cb_list->data,
211                                                  NOTIFICATION_TYPE_ONGOING);
212                 }
213
214                 noti_cb_list = noti_cb_list->next;
215         }
216 }
217 #endif
218
219 static void _notification_changed(const char *type)
220 {
221         DBusConnection *connection = NULL;
222         DBusMessage *message = NULL;
223         DBusError err;
224         dbus_bool_t ret;
225
226         if (!type) {
227                 NOTIFICATION_ERR("type is NULL");
228                 return;
229         }
230
231         dbus_error_init(&err);
232         connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
233         if (!connection) {
234                 NOTIFICATION_ERR("Fail to dbus_bus_get : %s", err.message);
235                 return;
236         }
237
238         message = dbus_message_new_signal(NOTI_DBUS_PATH,
239                                 NOTI_DBUS_INTERFACE,
240                                 type);
241
242         if (!message) {
243                 NOTIFICATION_ERR("fail to create dbus message");
244                 goto release_n_return;
245         }
246
247         ret = dbus_connection_send(connection, message, NULL);
248         if (!ret) {
249                 NOTIFICATION_ERR("fail to send dbus message : %s", type);
250                 goto release_n_return;
251         }
252
253         dbus_connection_flush(connection);
254         
255         NOTIFICATION_DBG("success to emit signal [%s]", type);
256
257 release_n_return:
258         dbus_error_free(&err);
259
260         if (message)
261                 dbus_message_unref(message);
262
263         if (connection)
264                 dbus_connection_unref(connection);
265 }
266
267 static DBusHandlerResult _dbus_signal_filter(DBusConnection *conn,
268                 DBusMessage *msg, void *user_data)
269 {
270         const char *interface = NULL;
271         
272         interface = dbus_message_get_interface(msg);
273         NOTIFICATION_DBG("path : %s", dbus_message_get_path(msg));
274         NOTIFICATION_DBG("interface : %s", interface);
275
276         if (strcmp(NOTI_DBUS_INTERFACE, interface))
277                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
278
279
280         switch (dbus_message_get_type(msg)) {
281                 case DBUS_MESSAGE_TYPE_SIGNAL:
282                         _notification_chagned_noti_cb(NULL);    
283                         return DBUS_HANDLER_RESULT_HANDLED;
284                 default:
285                         break;
286         }
287         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
288 }
289
290 static DBusConnection *_noti_changed_monitor_init()
291 {
292         DBusError err;
293         DBusConnection *conn = NULL;
294         char rule[1024];
295
296         dbus_error_init(&err);
297         conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
298         if (!conn) {
299                 printf("fail to get bus\n");
300                 return NULL;
301         }
302         dbus_connection_setup_with_g_main(conn, NULL);
303         snprintf(rule, 1024, 
304                 "path='%s',type='signal',interface='%s',member='%s'",
305                 NOTI_DBUS_PATH, 
306                 NOTI_DBUS_INTERFACE,
307                 NOTI_CHANGED_NOTI);
308
309         dbus_bus_add_match(conn, rule, &err);
310         if (dbus_connection_add_filter(conn,_dbus_signal_filter, 
311                                         NULL, NULL) == FALSE) {
312                 NOTIFICATION_ERR("fail to dbus_connection_add_filter");
313                 dbus_connection_close(conn);
314                 return NULL;
315         }
316
317         dbus_connection_set_exit_on_disconnect(conn, FALSE);
318         return conn;
319 }
320
321 static void _noti_chanaged_monitor_fini()
322 {
323         DBusConnection *conn = g_dbus_handle;
324         char rule[1024];
325
326         if (!conn)
327                 return;
328         dbus_connection_remove_filter(conn, _dbus_signal_filter, NULL);
329
330         snprintf(rule, 1024, 
331                 "path='%s',type='signal',interface='%s',member='%s'",
332                 NOTI_DBUS_PATH, 
333                 NOTI_DBUS_INTERFACE,
334                 NOTI_CHANGED_NOTI);
335         dbus_bus_remove_match(conn, rule, NULL);
336
337         dbus_connection_close(conn);
338         g_dbus_handle = NULL;
339 }       
340
341 /* notification_set_icon will be removed */
342 EXPORT_API notification_error_e notification_set_icon(notification_h noti,
343                                                       const char *icon_path)
344 {
345         int ret_err = NOTIFICATION_ERROR_NONE;
346
347         ret_err =
348             notification_set_image(noti, NOTIFICATION_IMAGE_TYPE_ICON,
349                                    icon_path);
350
351         return ret_err;
352 }
353
354 /* notification_get_icon will be removed */
355 EXPORT_API notification_error_e notification_get_icon(notification_h noti,
356                                                       char **icon_path)
357 {
358         int ret_err = NOTIFICATION_ERROR_NONE;
359         char *ret_image_path = NULL;
360
361         ret_err =
362             notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON,
363                                    &ret_image_path);
364
365         if (ret_err == NOTIFICATION_ERROR_NONE && icon_path != NULL) {
366                 *icon_path = ret_image_path;
367
368                 //NOTIFICATION_DBG("Get icon : %s", *icon_path);
369         }
370
371         return ret_err;
372 }
373
374 EXPORT_API notification_error_e notification_set_image(notification_h noti,
375                                                        notification_image_type_e type,
376                                                        const char *image_path)
377 {
378         bundle *b = NULL;
379         char buf_key[32] = { 0, };
380         const char *ret_val = NULL;
381
382         /* Check noti and image_path are valid data */
383         if (noti == NULL || image_path == NULL) {
384                 return NOTIFICATION_ERROR_INVALID_DATA;
385         }
386
387         /* Check image type is valid type */
388         if (type <= NOTIFICATION_IMAGE_TYPE_NONE
389             || type >= NOTIFICATION_IMAGE_TYPE_MAX) {
390                 return NOTIFICATION_ERROR_INVALID_DATA;
391         }
392
393         /* Check image path bundle is exist */
394         if (noti->b_image_path) {
395                 /* If image path bundle is exist, store local bundle value */
396                 b = noti->b_image_path;
397
398                 /* Set image type to key as char string type */
399                 snprintf(buf_key, sizeof(buf_key), "%d", type);
400
401                 /* Get value using key */
402                 ret_val = bundle_get_val(b, buf_key);
403                 if (ret_val != NULL) {
404                         /* If key is exist, remove this value to store new image path */
405                         bundle_del(b, buf_key);
406                 }
407
408                 /* Add new image path with type key */
409                 bundle_add(b, buf_key, image_path);
410         } else {
411                 /* If image path bundle is not exist, create new one */
412                 b = bundle_create();
413
414                 /* Set image type to key as char string type */
415                 snprintf(buf_key, sizeof(buf_key), "%d", type);
416
417                 /* Add new image path with type key */
418                 bundle_add(b, buf_key, image_path);
419
420                 /* Save to image path bundle */
421                 noti->b_image_path = b;
422         }
423
424         return NOTIFICATION_ERROR_NONE;
425 }
426
427 EXPORT_API notification_error_e notification_get_image(notification_h noti,
428                                                        notification_image_type_e type,
429                                                        char **image_path)
430 {
431         bundle *b = NULL;
432         char buf_key[32] = { 0, };
433         const char *ret_val = NULL;
434         const char *pkgname = NULL;
435
436         /* Check noti and image_path is valid data */
437         if (noti == NULL || image_path == NULL) {
438                 return NOTIFICATION_ERROR_INVALID_DATA;
439         }
440
441         /* Check image type is valid data */
442         if (type <= NOTIFICATION_IMAGE_TYPE_NONE
443             || type >= NOTIFICATION_IMAGE_TYPE_MAX) {
444                 return NOTIFICATION_ERROR_INVALID_DATA;
445         }
446
447         /* Check image path bundle exist */
448         if (noti->b_image_path) {
449                 /* If image path bundle exist, store local bundle data */
450                 b = noti->b_image_path;
451
452                 /* Set image type to key as char string type */
453                 snprintf(buf_key, sizeof(buf_key), "%d", type);
454
455                 /* Get value of key */
456                 ret_val = bundle_get_val(b, buf_key);
457
458                 *image_path = (char *)ret_val;
459         } else {
460                 /* If image path bundle does not exist, image path is NULL */
461                 *image_path = NULL;
462         }
463
464         /* If image path is NULL and type is ICON, icon path set from AIL */
465         /* order : user icon -> launch_pkgname icon -> caller_pkgname icon -> service app icon */
466         if (*image_path == NULL && type == NOTIFICATION_IMAGE_TYPE_ICON) {
467                 /* Check App icon path is already set */
468                 if (noti->app_icon_path != NULL) {
469                         /* image path will be app icon path */
470                         *image_path = noti->app_icon_path;
471                 } else {
472                         /* Get image path using launch_pkgname */
473                         if (noti->launch_pkgname != NULL) {
474                                 noti->app_icon_path =
475                                     _notification_get_icon(noti->launch_pkgname);
476                         }
477
478                         /* If app icon path is NULL, get image path using caller_pkgname */
479                         if (noti->app_icon_path == NULL
480                             && noti->caller_pkgname != NULL) {
481                                 noti->app_icon_path =
482                                     _notification_get_icon(noti->caller_pkgname);
483                         }
484
485                         /* If app icon path is NULL, get image path using service data */
486                         if (noti->app_icon_path == NULL
487                             && noti->b_service_single_launch != NULL) {
488                                 pkgname =
489                                     appsvc_get_pkgname(noti->b_service_single_launch);
490                                 if (pkgname != NULL) {
491                                         noti->app_icon_path =
492                                             _notification_get_icon(pkgname);
493                                 }
494                         }
495
496                         *image_path = noti->app_icon_path;
497                 }
498         }
499
500         return NOTIFICATION_ERROR_NONE;
501 }
502
503 EXPORT_API notification_error_e notification_set_time(notification_h noti,
504                                                       time_t input_time)
505 {
506         /* Check noti is valid data */
507         if (noti == NULL) {
508                 return NOTIFICATION_ERROR_INVALID_DATA;
509         }
510
511         if (input_time == 0) {
512                 /* If input time is 0, set current time */
513                 noti->time = time(NULL);
514         } else {
515                 /* save input time */
516                 noti->time = input_time;
517         }
518
519         return NOTIFICATION_ERROR_NONE;
520 }
521
522 EXPORT_API notification_error_e notification_get_time(notification_h noti,
523                                                       time_t * ret_time)
524 {
525         /* Check noti and time is valid data */
526         if (noti == NULL || ret_time == NULL) {
527                 return NOTIFICATION_ERROR_INVALID_DATA;
528         }
529
530         /* Set time infomation */
531         *ret_time = noti->time;
532
533         return NOTIFICATION_ERROR_NONE;
534 }
535
536 EXPORT_API notification_error_e notification_get_insert_time(notification_h noti,
537                                                              time_t * ret_time)
538 {
539         /* Check noti and ret_time is valid data */
540         if (noti == NULL || ret_time == NULL) {
541                 return NOTIFICATION_ERROR_INVALID_DATA;
542         }
543
544         /* Set insert time information */
545         *ret_time = noti->insert_time;
546
547         return NOTIFICATION_ERROR_NONE;
548 }
549
550 EXPORT_API notification_error_e notification_set_title(notification_h noti,
551                                                        const char *title,
552                                                        const char *loc_title)
553 {
554         int noti_err = NOTIFICATION_ERROR_NONE;
555
556         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
557                                          title, loc_title,
558                                          NOTIFICATION_VARIABLE_TYPE_NONE);
559
560         return noti_err;
561 }
562
563 EXPORT_API notification_error_e notification_get_title(notification_h noti,
564                                                        char **title,
565                                                        char **loc_title)
566 {
567         int noti_err = NOTIFICATION_ERROR_NONE;
568         char *ret_text = NULL;
569
570         noti_err =
571             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
572                                   &ret_text);
573
574         if (title != NULL) {
575                 *title = ret_text;
576         }
577
578         if (loc_title != NULL) {
579                 *loc_title = NULL;
580         }
581
582         return noti_err;
583 }
584
585 EXPORT_API notification_error_e notification_set_content(notification_h noti,
586                                                          const char *content,
587                                                          const char *loc_content)
588 {
589         int noti_err = NOTIFICATION_ERROR_NONE;
590
591         noti_err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
592                                          content, loc_content,
593                                          NOTIFICATION_VARIABLE_TYPE_NONE);
594
595         return noti_err;
596 }
597
598 EXPORT_API notification_error_e notification_get_content(notification_h noti,
599                                                          char **content,
600                                                          char **loc_content)
601 {
602         int noti_err = NOTIFICATION_ERROR_NONE;
603         char *ret_text = NULL;
604
605         noti_err =
606             notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
607                                   &ret_text);
608
609         if (content != NULL) {
610                 *content = ret_text;
611         }
612
613         if (loc_content != NULL) {
614                 *loc_content = NULL;
615         }
616
617         return noti_err;
618
619 #if 0
620         ret =
621             vconf_get_bool
622             (VCONFKEY_SETAPPL_STATE_TICKER_NOTI_DISPLAY_CONTENT_BOOL, &boolval);
623
624         if (ret == -1 || boolval == 0) {
625                 if (content != NULL && noti->default_content != NULL) {
626                         *content = noti->default_content;
627                 }
628
629                 if (loc_content != NULL && noti->loc_default_content != NULL) {
630                         *loc_content = noti->loc_default_content;
631                 }
632         }
633 #endif
634 }
635
636 EXPORT_API notification_error_e notification_set_text(notification_h noti,
637                                                       notification_text_type_e type,
638                                                       const char *text,
639                                                       const char *key,
640                                                       int args_type, ...)
641 {
642         bundle *b = NULL;
643         char buf_key[32] = { 0, };
644         char buf_val[1024] = { 0, };
645         const char *ret_val = NULL;
646         va_list var_args;
647         notification_variable_type_e var_type;
648         int num_args = 0;
649         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
650         int var_value_int = 0;
651         double var_value_double = 0.0;
652         char *var_value_string = NULL;
653         notification_count_pos_type_e var_value_count =
654             NOTIFICATION_COUNT_POS_NONE;
655
656         /* Check noti is valid data */
657         if (noti == NULL) {
658                 return NOTIFICATION_ERROR_INVALID_DATA;
659         }
660
661         /* Check text type is valid type */
662         if (type <= NOTIFICATION_TEXT_TYPE_NONE
663             || type >= NOTIFICATION_TEXT_TYPE_MAX) {
664                 return NOTIFICATION_ERROR_INVALID_DATA;
665         }
666
667         /* Check text bundle exist */
668         if (text != NULL) {
669                 if (noti->b_text != NULL) {
670                         /* If text bundle exist, store local bundle data */
671                         b = noti->b_text;
672
673                         /* Make type to key as char string */
674                         snprintf(buf_key, sizeof(buf_key), "%d", type);
675
676                         /* Get value using type key */
677                         ret_val = bundle_get_val(b, buf_key);
678                         if (ret_val != NULL) {
679                                 /* If value exist, remove this to add new value */
680                                 bundle_del(b, buf_key);
681                         }
682
683                         snprintf(buf_val, sizeof(buf_val), "%s", text);
684
685                         /* Add new text value */
686                         bundle_add(b, buf_key, buf_val);
687                 } else {
688                         /* If text bundle does not exist, create new one */
689                         b = bundle_create();
690
691                         /* Make type to key as char string */
692                         snprintf(buf_key, sizeof(buf_key), "%d", type);
693
694                         snprintf(buf_val, sizeof(buf_val), "%s", text);
695
696                         /* Add new text value */
697                         bundle_add(b, buf_key, buf_val);
698
699                         /* Save text bundle */
700                         noti->b_text = b;
701                 }
702         } else {
703                 /* Reset if text is NULL */
704                 if (noti->b_text != NULL) {
705                         /* If text bundle exist, store local bundle data */
706                         b = noti->b_text;
707
708                         /* Make type to key as char string */
709                         snprintf(buf_key, sizeof(buf_key), "%d", type);
710
711                         /* Get value using type key */
712                         ret_val = bundle_get_val(b, buf_key);
713                         if (ret_val != NULL) {
714                                 /* If value exist, remove this */
715                                 bundle_del(b, buf_key);
716                         }
717                 }
718         }
719
720         /* Save key if key is valid data */
721         if (key != NULL) {
722                 /* Check key bundle exist */
723                 if (noti->b_key != NULL) {
724                         /* If key bundle exist,  store local bundle data */
725                         b = noti->b_key;
726
727                         /* Make type to key as char string */
728                         snprintf(buf_key, sizeof(buf_key), "%d", type);
729
730                         /* Get value using type key */
731                         ret_val = bundle_get_val(b, buf_key);
732                         if (ret_val != NULL) {
733                                 /* If value exist, remove this to add new value */
734                                 bundle_del(b, buf_key);
735                         }
736
737                         snprintf(buf_val, sizeof(buf_val), "%s", key);
738
739                         /* Add new key value */
740                         bundle_add(b, buf_key, buf_val);
741                 } else {
742                         /* If key bundle does not exist, create new one */
743                         b = bundle_create();
744
745                         /* Make type to key as char string */
746                         snprintf(buf_key, sizeof(buf_key), "%d", type);
747
748                         snprintf(buf_val, sizeof(buf_val), "%s", key);
749
750                         /* Add new key value */
751                         bundle_add(b, buf_key, buf_val);
752
753                         /* Save key bundle */
754                         noti->b_key = b;
755                 }
756         } else {
757                 /* Reset if key is NULL */
758                 if (noti->b_key != NULL) {
759                         /* If key bundle exist,  store local bundle data */
760                         b = noti->b_key;
761
762                         /* Make type to key as char string */
763                         snprintf(buf_key, sizeof(buf_key), "%d", type);
764
765                         /* Get value using type key */
766                         ret_val = bundle_get_val(b, buf_key);
767                         if (ret_val != NULL) {
768                                 /* If value exist, remove this */
769                                 bundle_del(b, buf_key);
770                         }
771                 }
772         }
773
774         if (noti->b_format_args != NULL) {
775                 b = noti->b_format_args;
776         } else {
777                 b = bundle_create();
778         }
779
780         va_start(var_args, args_type);
781
782         var_type = args_type;
783         num_args = 0;
784
785         while (var_type != NOTIFICATION_VARIABLE_TYPE_NONE) {
786                 /* Type */
787                 snprintf(buf_key, sizeof(buf_key), "%dtype%d", type, num_args);
788                 snprintf(buf_val, sizeof(buf_val), "%d", var_type);
789
790                 ret_val = bundle_get_val(b, buf_key);
791                 if (ret_val != NULL) {
792                         bundle_del(b, buf_key);
793                 }
794
795                 bundle_add(b, buf_key, buf_val);
796
797                 switch (var_type) {
798                 case NOTIFICATION_VARIABLE_TYPE_INT:
799                         var_value_int = va_arg(var_args, int);
800
801                         /* Value */
802                         snprintf(buf_key, sizeof(buf_key), "%dvalue%d", type,
803                                  num_args);
804                         snprintf(buf_val, sizeof(buf_val), "%d", var_value_int);
805
806                         ret_val = bundle_get_val(b, buf_key);
807                         if (ret_val != NULL) {
808                                 bundle_del(b, buf_key);
809                         }
810
811                         bundle_add(b, buf_key, buf_val);
812                         break;
813                 case NOTIFICATION_VARIABLE_TYPE_DOUBLE:
814                         var_value_double = va_arg(var_args, double);
815
816                         /* Value */
817                         snprintf(buf_key, sizeof(buf_key), "%dvalue%d", type,
818                                  num_args);
819                         snprintf(buf_val, sizeof(buf_val), "%.2f",
820                                  var_value_double);
821
822                         ret_val = bundle_get_val(b, buf_key);
823                         if (ret_val != NULL) {
824                                 bundle_del(b, buf_key);
825                         }
826
827                         bundle_add(b, buf_key, buf_val);
828                         break;
829                 case NOTIFICATION_VARIABLE_TYPE_STRING:
830                         var_value_string = va_arg(var_args, char *);
831
832                         /* Value */
833                         snprintf(buf_key, sizeof(buf_key), "%dvalue%d", type,
834                                  num_args);
835                         snprintf(buf_val, sizeof(buf_val), "%s",
836                                  var_value_string);
837
838                         ret_val = bundle_get_val(b, buf_key);
839                         if (ret_val != NULL) {
840                                 bundle_del(b, buf_key);
841                         }
842
843                         bundle_add(b, buf_key, buf_val);
844                         break;
845                 case NOTIFICATION_VARIABLE_TYPE_COUNT:
846                         var_value_count =
847                             va_arg(var_args, notification_count_pos_type_e);
848
849                         /* Value */
850                         snprintf(buf_key, sizeof(buf_key), "%dvalue%d", type,
851                                  num_args);
852                         snprintf(buf_val, sizeof(buf_val), "%d",
853                                  var_value_count);
854
855                         ret_val = bundle_get_val(b, buf_key);
856                         if (ret_val != NULL) {
857                                 bundle_del(b, buf_key);
858                         }
859
860                         bundle_add(b, buf_key, buf_val);
861                         break;
862                 default:
863                         NOTIFICATION_ERR("Error. invalid variable type. : %d",
864                                          var_type);
865                         noti_err = NOTIFICATION_ERROR_INVALID_DATA;
866                         break;
867                 }
868
869                 num_args++;
870                 var_type = va_arg(var_args, notification_variable_type_e);
871         }
872         va_end(var_args);
873
874         if (noti_err == NOTIFICATION_ERROR_NONE) {
875                 noti->num_format_args = num_args;
876         } else {
877                 noti->num_format_args = 0;
878         }
879
880         snprintf(buf_key, sizeof(buf_key), "num%d", type);
881         snprintf(buf_val, sizeof(buf_val), "%d", noti->num_format_args);
882
883         ret_val = bundle_get_val(b, buf_key);
884         if (ret_val != NULL) {
885                 bundle_del(b, buf_key);
886         }
887
888         bundle_add(b, buf_key, buf_val);
889
890         noti->b_format_args = b;
891
892         return noti_err;
893 }
894
895 EXPORT_API notification_error_e notification_get_text(notification_h noti,
896                                                       notification_text_type_e type,
897                                                       char **text)
898 {
899         bundle *b = NULL;
900         char buf_key[32] = { 0, };
901         const char *ret_val = NULL;
902         const char *pkgname = NULL;
903         const char *get_str = NULL;
904         const char *get_check_type_str = NULL;
905         int ret = 0;
906         int boolval = 0;
907         notification_text_type_e check_type = NOTIFICATION_TEXT_TYPE_NONE;
908         int display_option_flag = 0;
909
910         char *temp_str = NULL;
911         char result_str[1024] = { 0, };
912         char buf_str[1024] = { 0, };
913         int num_args = 0;
914         notification_variable_type_e ret_var_type = 0;
915         int ret_variable_int = 0;
916         double ret_variable_double = 0.0;
917
918         /* Check noti is valid data */
919         if (noti == NULL || text == NULL) {
920                 return NOTIFICATION_ERROR_INVALID_DATA;
921         }
922
923         /* Check text type is valid type */
924         if (type <= NOTIFICATION_TEXT_TYPE_NONE
925             || type >= NOTIFICATION_TEXT_TYPE_MAX) {
926                 return NOTIFICATION_ERROR_INVALID_DATA;
927         }
928
929         /* Check key */
930         if (noti->b_key != NULL) {
931                 b = noti->b_key;
932
933                 /* Get text domain and dir */
934                 _notification_get_text_domain(noti);
935
936                 snprintf(buf_key, sizeof(buf_key), "%d", type);
937
938                 ret_val = bundle_get_val(b, buf_key);
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                 } else if (ret_val != NULL) {
946                         /* Get system string */
947                         get_str = dgettext("sys_string", ret_val);
948                 } else {
949                         get_str = NULL;
950                 }
951         }
952
953         if (get_str == NULL && noti->b_text != NULL) {
954                 b = noti->b_text;
955                 /* Get basic text */
956                 snprintf(buf_key, sizeof(buf_key), "%d", type);
957
958                 get_str = bundle_get_val(b, buf_key);
959         }
960
961         check_type = type;
962
963         /* Set display option is off type when option is off, type is noti */
964         if (get_str != NULL && display_option_flag == 1
965             && noti->type == NOTIFICATION_TYPE_NOTI) {
966                 if (type == NOTIFICATION_TEXT_TYPE_CONTENT
967                     || type == NOTIFICATION_TEXT_TYPE_GROUP_CONTENT) {
968                         /* Set check_type to option content string */
969                         if (type == NOTIFICATION_TEXT_TYPE_CONTENT) {
970                                 check_type =
971                                     NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF;
972                         } else if (type == NOTIFICATION_TEXT_TYPE_GROUP_CONTENT) {
973                                 check_type =
974                                     NOTIFICATION_TEXT_TYPE_GROUP_CONTENT_FOR_DISPLAY_OPTION_IS_OFF;
975                         }
976
977                         /* Check key */
978                         if (noti->b_key != NULL) {
979                                 b = noti->b_key;
980
981                                 /* Get text domain and dir */
982                                 _notification_get_text_domain(noti);
983
984                                 snprintf(buf_key, sizeof(buf_key), "%d",
985                                          check_type);
986
987                                 ret_val = bundle_get_val(b, buf_key);
988                                 if (ret_val != NULL && noti->domain != NULL
989                                     && noti->dir != NULL) {
990                                         /* Get application string */
991                                         bindtextdomain(noti->domain, noti->dir);
992
993                                         get_check_type_str =
994                                             dgettext(noti->domain, ret_val);
995                                 } else if (ret_val != NULL) {
996                                         /* Get system string */
997                                         get_check_type_str =
998                                             dgettext("sys_string", ret_val);
999                                 } else {
1000                                         get_check_type_str = NULL;
1001                                 }
1002                         }
1003
1004                         if (get_check_type_str == NULL && noti->b_text != NULL) {
1005                                 b = noti->b_text;
1006                                 /* Get basic text */
1007                                 snprintf(buf_key, sizeof(buf_key), "%d",
1008                                          check_type);
1009
1010                                 get_check_type_str = bundle_get_val(b, buf_key);
1011                         }
1012                 }
1013
1014                 if (get_check_type_str != NULL) {
1015                         /* Replace option off type string */
1016                         get_str = get_check_type_str;
1017                 } else {
1018                         /* Set default string */
1019                         get_str =
1020                             dgettext("sys_string", "IDS_COM_POP_MISSED_EVENT");
1021                 }
1022         }
1023
1024         if (get_str != NULL) {
1025                 /* Get number format args */
1026                 b = noti->b_format_args;
1027                 noti->num_format_args = 0;
1028
1029                 if (b != NULL) {
1030                         snprintf(buf_key, sizeof(buf_key), "num%d", check_type);
1031                         ret_val = bundle_get_val(b, buf_key);
1032                         if (ret_val != NULL) {
1033                                 noti->num_format_args = atoi(ret_val);
1034                         }
1035                 }
1036
1037                 if (noti->num_format_args == 0) {
1038                         *text = (char *)get_str;
1039                 } else {
1040                         /* Check first variable is count, LEFT pos */
1041                         snprintf(buf_key, sizeof(buf_key), "%dtype%d",
1042                                  check_type, num_args);
1043                         ret_val = bundle_get_val(b, buf_key);
1044                         ret_var_type = atoi(ret_val);
1045
1046                         if (ret_var_type == NOTIFICATION_VARIABLE_TYPE_COUNT) {
1047                                 /* Get var Value */
1048                                 snprintf(buf_key, sizeof(buf_key), "%dvalue%d",
1049                                          check_type, num_args);
1050                                 ret_val = bundle_get_val(b, buf_key);
1051                                 ret_variable_int = atoi(ret_val);
1052
1053                                 if (ret_variable_int ==
1054                                     NOTIFICATION_COUNT_POS_LEFT) {
1055                                         notification_noti_get_count(noti->type,
1056                                                                     noti->caller_pkgname,
1057                                                                     noti->group_id,
1058                                                                     noti->priv_id,
1059                                                                     &ret_variable_int);
1060                                         snprintf(buf_str, sizeof(buf_str),
1061                                                  "%d ", ret_variable_int);
1062                                         strncat(result_str, buf_str,
1063                                                 sizeof(result_str));
1064
1065                                         num_args++;
1066                                 }
1067
1068                         }
1069
1070                         /* Check variable IN pos */
1071                         for (temp_str = (char *)get_str; *temp_str != '\0';
1072                              temp_str++) {
1073                                 if (*temp_str != '%') {
1074                                         strncat(result_str, temp_str, 1);
1075                                 } else {
1076                                         if (*(temp_str + 1) == '%') {
1077                                                 strncat(result_str, temp_str,
1078                                                         1);
1079                                         } else if (*(temp_str + 1) == 'd') {
1080                                                 /* Get var Type */
1081                                                 ret_variable_int = 0;
1082
1083                                                 snprintf(buf_key,
1084                                                          sizeof(buf_key),
1085                                                          "%dtype%d", check_type,
1086                                                          num_args);
1087                                                 ret_val =
1088                                                     bundle_get_val(b, buf_key);
1089                                                 ret_var_type = atoi(ret_val);
1090                                                 if (ret_var_type ==
1091                                                     NOTIFICATION_VARIABLE_TYPE_COUNT)
1092                                                 {
1093                                                         /* Get notification count */
1094                                                         notification_noti_get_count
1095                                                             (noti->type,
1096                                                              noti->caller_pkgname,
1097                                                              noti->group_id,
1098                                                              noti->priv_id,
1099                                                              &ret_variable_int);
1100                                                 } else {
1101                                                         /* Get var Value */
1102                                                         snprintf(buf_key,
1103                                                                  sizeof
1104                                                                  (buf_key),
1105                                                                  "%dvalue%d",
1106                                                                  check_type,
1107                                                                  num_args);
1108                                                         ret_val =
1109                                                             bundle_get_val(b,
1110                                                                            buf_key);
1111                                                         ret_variable_int =
1112                                                             atoi(ret_val);
1113                                                 }
1114
1115                                                 snprintf(buf_str,
1116                                                          sizeof(buf_str), "%d",
1117                                                          ret_variable_int);
1118                                                 strncat(result_str, buf_str,
1119                                                         sizeof(result_str));
1120
1121                                                 temp_str++;
1122
1123                                                 num_args++;
1124                                         } else if (*(temp_str + 1) == 's') {
1125                                                 /* Get var Value */
1126                                                 snprintf(buf_key,
1127                                                          sizeof(buf_key),
1128                                                          "%dvalue%d",
1129                                                          check_type, num_args);
1130                                                 ret_val =
1131                                                     bundle_get_val(b, buf_key);
1132
1133                                                 snprintf(buf_str,
1134                                                          sizeof(buf_str), "%s",
1135                                                          ret_val);
1136                                                 strncat(result_str, buf_str,
1137                                                         sizeof(result_str));
1138
1139                                                 temp_str++;
1140
1141                                                 num_args++;
1142                                         } else if (*(temp_str + 1) == 'f') {
1143                                                 /* Get var Value */
1144                                                 snprintf(buf_key,
1145                                                          sizeof(buf_key),
1146                                                          "%dvalue%d",
1147                                                          check_type, num_args);
1148                                                 ret_val =
1149                                                     bundle_get_val(b, buf_key);
1150                                                 ret_variable_double =
1151                                                     atof(ret_val);
1152
1153                                                 snprintf(buf_str,
1154                                                          sizeof(buf_str),
1155                                                          "%.2f",
1156                                                          ret_variable_double);
1157                                                 strncat(result_str, buf_str,
1158                                                         sizeof(result_str));
1159
1160                                                 temp_str++;
1161
1162                                                 num_args++;
1163                                         }
1164                                 }
1165
1166                         }
1167
1168                         /* Check last variable is count, LEFT pos */
1169                         if (num_args < noti->num_format_args) {
1170                                 snprintf(buf_key, sizeof(buf_key), "%dtype%d",
1171                                          check_type, num_args);
1172                                 ret_val = bundle_get_val(b, buf_key);
1173                                 ret_var_type = atoi(ret_val);
1174                                 if (ret_var_type ==
1175                                     NOTIFICATION_VARIABLE_TYPE_COUNT) {
1176                                         /* Get var Value */
1177                                         snprintf(buf_key, sizeof(buf_key),
1178                                                  "%dvalue%d", check_type,
1179                                                  num_args);
1180                                         ret_val = bundle_get_val(b, buf_key);
1181                                         ret_variable_int = atoi(ret_val);
1182
1183                                         if (ret_variable_int ==
1184                                             NOTIFICATION_COUNT_POS_RIGHT) {
1185                                                 notification_noti_get_count
1186                                                     (noti->type,
1187                                                      noti->caller_pkgname,
1188                                                      noti->group_id,
1189                                                      noti->priv_id,
1190                                                      &ret_variable_int);
1191                                                 snprintf(buf_str,
1192                                                          sizeof(buf_str), " %d",
1193                                                          ret_variable_int);
1194                                                 strncat(result_str, buf_str,
1195                                                         sizeof(result_str));
1196
1197                                                 num_args++;
1198                                         }
1199
1200                                 }
1201                         }
1202
1203                         switch (check_type) {
1204                         case NOTIFICATION_TEXT_TYPE_TITLE:
1205                         case NOTIFICATION_TEXT_TYPE_GROUP_TITLE:
1206                                 if (noti->temp_title != NULL)
1207                                         free(noti->temp_title);
1208
1209                                 noti->temp_title = strdup(result_str);
1210
1211                                 *text = noti->temp_title;
1212                                 break;
1213                         case NOTIFICATION_TEXT_TYPE_CONTENT:
1214                         case NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF:
1215                         case NOTIFICATION_TEXT_TYPE_GROUP_CONTENT:
1216                         case NOTIFICATION_TEXT_TYPE_GROUP_CONTENT_FOR_DISPLAY_OPTION_IS_OFF:
1217                                 if (noti->temp_content !=
1218                                     NULL)
1219                                         free(noti->temp_content);
1220
1221                                 noti->temp_content = strdup(result_str);
1222
1223                                 *text = noti->temp_content;
1224                                 break;
1225                         default:
1226                                 break;
1227                         }
1228
1229                 }
1230
1231         } else {
1232                 if (check_type == NOTIFICATION_TEXT_TYPE_TITLE
1233                     || check_type == NOTIFICATION_TEXT_TYPE_GROUP_TITLE) {
1234                         /* Remove app name if exist, because pkgname is changed according to language setting */
1235                         if (noti->app_name != NULL) {
1236                                 free(noti->app_name);
1237                                 noti->app_name = NULL;
1238                         }
1239
1240                         /* First, get app name from launch_pkgname */
1241                         if (noti->launch_pkgname != NULL) {
1242                                 noti->app_name =
1243                                     _notification_get_name(noti->
1244                                                            launch_pkgname);
1245                         }
1246
1247                         /* Second, get app name from caller_pkgname */
1248                         if (noti->app_name == NULL
1249                             && noti->caller_pkgname != NULL) {
1250                                 noti->app_name =
1251                                     _notification_get_name(noti->
1252                                                            caller_pkgname);
1253                         }
1254
1255                         /* Third, get app name from service data */
1256                         if (noti->app_name == NULL
1257                             && noti->b_service_single_launch != NULL) {
1258                                 pkgname =
1259                                     appsvc_get_pkgname(noti->
1260                                                        b_service_single_launch);
1261
1262                                 if (pkgname != NULL) {
1263                                         noti->app_name =
1264                                             _notification_get_name(pkgname);
1265                                 }
1266                         }
1267
1268                         *text = noti->app_name;
1269                 } else {
1270                         *text = NULL;
1271                 }
1272         }
1273
1274         NOTIFICATION_INFO("Get text : %s", *text);
1275
1276         return NOTIFICATION_ERROR_NONE;
1277 }
1278
1279 EXPORT_API notification_error_e notification_set_text_domain(notification_h noti,
1280                                                              const char *domain,
1281                                                              const char *dir)
1282 {
1283         /* check noti and domain is valid data */
1284         if (noti == NULL || domain == NULL) {
1285                 return NOTIFICATION_ERROR_INVALID_DATA;
1286         }
1287
1288         /* Check domain */
1289         if (noti->domain) {
1290                 /* Remove previous domain */
1291                 free(noti->domain);
1292         }
1293         /* Copy domain */
1294         noti->domain = strdup(domain);
1295
1296         /* Check locale dir */
1297         if (noti->dir) {
1298                 /* Remove previous locale dir */
1299                 free(noti->dir);
1300         }
1301         /* Copy locale dir */
1302         noti->dir = strdup(dir);
1303
1304         return NOTIFICATION_ERROR_NONE;
1305 }
1306
1307 EXPORT_API notification_error_e notification_get_text_domain(notification_h noti,
1308                                                              char **domain,
1309                                                              char **dir)
1310 {
1311         /* Check noti is valid data */
1312         if (noti == NULL) {
1313                 return NOTIFICATION_ERROR_INVALID_DATA;
1314         }
1315
1316         /* Get domain */
1317         if (domain != NULL && noti->domain != NULL) {
1318                 *domain = noti->domain;
1319         }
1320
1321         /* Get locale dir */
1322         if (dir != NULL && noti->dir != NULL) {
1323                 *dir = noti->dir;
1324         }
1325
1326         return NOTIFICATION_ERROR_NONE;
1327 }
1328
1329 EXPORT_API notification_error_e notification_set_sound(notification_h noti,
1330                                                        notification_sound_type_e type,
1331                                                        const char *path)
1332 {
1333         /* Check noti is valid data */
1334         if (noti == NULL) {
1335                 return NOTIFICATION_ERROR_INVALID_DATA;
1336         }
1337
1338         /* Check type is valid */
1339         if (type < NOTIFICATION_SOUND_TYPE_NONE
1340             || type >= NOTIFICATION_SOUND_TYPE_MAX) {
1341                 return NOTIFICATION_ERROR_INVALID_DATA;
1342         }
1343
1344         /* Save sound type */
1345         noti->sound_type = type;
1346
1347         /* Save sound path if user data type */
1348         if (type == NOTIFICATION_SOUND_TYPE_USER_DATA && path != NULL) {
1349                 if (noti->sound_path != NULL) {
1350                         free(noti->sound_path);
1351                 }
1352
1353                 noti->sound_path = strdup(path);
1354         } else {
1355                 if (noti->sound_path != NULL) {
1356                         free(noti->sound_path);
1357                         noti->sound_path = NULL;
1358                 }
1359         }
1360
1361         return NOTIFICATION_ERROR_NONE;
1362 }
1363
1364 EXPORT_API notification_error_e notification_get_sound(notification_h noti,
1365                                                        notification_sound_type_e *type,
1366                                                        const char **path)
1367 {
1368         /* check noti and type is valid data */
1369         if (noti == NULL || type == NULL) {
1370                 return NOTIFICATION_ERROR_INVALID_DATA;
1371         }
1372
1373         /* Set sound type */
1374         *type = noti->sound_type;
1375
1376         /* Set sound path if user data type */
1377         if (noti->sound_type == NOTIFICATION_SOUND_TYPE_USER_DATA
1378             && path != NULL) {
1379                 *path = noti->sound_path;
1380         }
1381
1382         return NOTIFICATION_ERROR_NONE;
1383 }
1384
1385 EXPORT_API notification_error_e notification_set_vibration(notification_h noti,
1386                                                            notification_vibration_type_e type,
1387                                                            const char *path)
1388 {
1389         /* Check noti is valid data */
1390         if (noti == NULL) {
1391                 return NOTIFICATION_ERROR_INVALID_DATA;
1392         }
1393
1394         /* Check type is valid */
1395         if (type < NOTIFICATION_VIBRATION_TYPE_NONE
1396             || type >= NOTIFICATION_VIBRATION_TYPE_MAX) {
1397                 return NOTIFICATION_ERROR_INVALID_DATA;
1398         }
1399
1400         /* Save vibration type */
1401         noti->vibration_type = type;
1402
1403         /* Save sound path if user data type */
1404         if (type == NOTIFICATION_VIBRATION_TYPE_USER_DATA && path != NULL) {
1405                 if (noti->vibration_path != NULL) {
1406                         free(noti->vibration_path);
1407                 }
1408
1409                 noti->vibration_path = strdup(path);
1410         } else {
1411                 if (noti->vibration_path != NULL) {
1412                         free(noti->vibration_path);
1413                         noti->vibration_path = NULL;
1414                 }
1415         }
1416
1417         return NOTIFICATION_ERROR_NONE;
1418
1419 }
1420
1421 EXPORT_API notification_error_e notification_get_vibration(notification_h noti,
1422                                                            notification_vibration_type_e *type,
1423                                                            const char **path)
1424 {
1425         /* check noti and type is valid data */
1426         if (noti == NULL || type == NULL) {
1427                 return NOTIFICATION_ERROR_INVALID_DATA;
1428         }
1429
1430         /* Set vibration type */
1431         *type = noti->vibration_type;
1432
1433         /* Set sound path if user data type */
1434         if (noti->vibration_type == NOTIFICATION_VIBRATION_TYPE_USER_DATA
1435             && path != NULL) {
1436                 *path = noti->vibration_path;
1437         }
1438
1439         return NOTIFICATION_ERROR_NONE;
1440 }
1441
1442 EXPORT_API notification_error_e notification_set_application(notification_h noti,
1443                                                              const char *pkgname)
1444 {
1445         if (noti == NULL || pkgname == NULL) {
1446                 return NOTIFICATION_ERROR_INVALID_DATA;
1447         }
1448
1449         if (noti->launch_pkgname) {
1450                 free(noti->launch_pkgname);
1451         }
1452
1453         noti->launch_pkgname = strdup(pkgname);
1454
1455         return NOTIFICATION_ERROR_NONE;
1456 }
1457
1458 EXPORT_API notification_error_e notification_get_application(notification_h noti,
1459                                                              char **pkgname)
1460 {
1461         if (noti == NULL || pkgname == NULL) {
1462                 return NOTIFICATION_ERROR_INVALID_DATA;
1463         }
1464
1465         if (noti->launch_pkgname) {
1466                 *pkgname = noti->launch_pkgname;
1467         } else {
1468                 *pkgname = noti->caller_pkgname;
1469         }
1470
1471         return NOTIFICATION_ERROR_NONE;
1472 }
1473
1474 EXPORT_API notification_error_e notification_set_args(notification_h noti,
1475                                                       bundle * args,
1476                                                       bundle * group_args)
1477 {
1478         if (noti == NULL || args == NULL) {
1479                 return NOTIFICATION_ERROR_INVALID_DATA;
1480         }
1481
1482         if (noti->args) {
1483                 bundle_free(noti->args);
1484         }
1485
1486         noti->args = bundle_dup(args);
1487
1488         if (noti->group_args) {
1489                 bundle_free(noti->group_args);
1490                 noti->group_args = NULL;
1491         }
1492
1493         if (group_args != NULL) {
1494                 noti->group_args = bundle_dup(group_args);
1495         }
1496
1497         return NOTIFICATION_ERROR_NONE;
1498 }
1499
1500 EXPORT_API notification_error_e notification_get_args(notification_h noti,
1501                                                       bundle ** args,
1502                                                       bundle ** group_args)
1503 {
1504         if (noti == NULL || args == NULL) {
1505                 return NOTIFICATION_ERROR_INVALID_DATA;
1506         }
1507
1508         if (noti->args) {
1509                 *args = noti->args;
1510         } else {
1511                 *args = NULL;
1512         }
1513
1514         if (group_args != NULL && noti->group_args) {
1515                 *group_args = noti->group_args;
1516         }
1517
1518         return NOTIFICATION_ERROR_NONE;
1519 }
1520
1521 EXPORT_API notification_error_e notification_set_execute_option(notification_h noti,
1522                                                                 notification_execute_type_e type,
1523                                                                 const char *text,
1524                                                                 const char *key,
1525                                                                 bundle *service_handle)
1526 {
1527         char buf_key[32] = { 0, };
1528         const char *ret_val = NULL;
1529         bundle *b = NULL;
1530
1531         if (noti == NULL) {
1532                 return NOTIFICATION_ERROR_INVALID_DATA;
1533         }
1534
1535         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
1536             || type >= NOTIFICATION_EXECUTE_TYPE_MAX) {
1537                 return NOTIFICATION_ERROR_INVALID_DATA;
1538         }
1539
1540         /* Create execute option bundle if does not exist */
1541         if (noti->b_execute_option != NULL) {
1542                 noti->b_execute_option = bundle_create();
1543         }
1544
1545         b = noti->b_execute_option;
1546
1547         /* Save text */
1548         if (text != NULL) {
1549                 /* Make text key */
1550                 snprintf(buf_key, sizeof(buf_key), "text%d", type);
1551
1552                 /* Check text key exist */
1553                 ret_val = bundle_get_val(b, buf_key);
1554                 if (ret_val != NULL) {
1555                         /* Remove previous data */
1556                         bundle_del(b, buf_key);
1557                 }
1558
1559                 /* Add text data */
1560                 bundle_add(b, buf_key, text);
1561         }
1562
1563         /* Save key */
1564         if (key != NULL) {
1565                 /* Make key key */
1566                 snprintf(buf_key, sizeof(buf_key), "key%d", type);
1567
1568                 /* Check key key exist */
1569                 ret_val = bundle_get_val(b, buf_key);
1570                 if (ret_val != NULL) {
1571                         /* Remove previous data */
1572                         bundle_del(b, buf_key);
1573                 }
1574
1575                 /* Add text data */
1576                 bundle_add(b, buf_key, key);
1577         }
1578
1579         switch (type) {
1580         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
1581                 /* Remove previous data if exist */
1582                 if (noti->b_service_responding != NULL) {
1583                         bundle_free(noti->b_service_responding);
1584                         noti->b_service_responding = NULL;
1585                 }
1586
1587                 /* Save service handle */
1588                 if (service_handle != NULL) {
1589                         noti->b_service_responding = bundle_dup(service_handle);
1590                 }
1591                 break;
1592         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
1593                 /* Remove previous data if exist */
1594                 if (noti->b_service_single_launch != NULL) {
1595                         bundle_free(noti->b_service_single_launch);
1596                         noti->b_service_single_launch = NULL;
1597                 }
1598
1599                 /* Save service handle */
1600                 if (service_handle != NULL) {
1601                         noti->b_service_single_launch =
1602                             bundle_dup(service_handle);
1603                 }
1604                 break;
1605         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
1606                 /* Remove previous data if exist */
1607                 if (noti->b_service_multi_launch != NULL) {
1608                         bundle_free(noti->b_service_multi_launch);
1609                         noti->b_service_multi_launch = NULL;
1610                 }
1611
1612                 /* Save service handle */
1613                 if (service_handle != NULL) {
1614                         noti->b_service_multi_launch =
1615                             bundle_dup(service_handle);
1616                 }
1617                 break;
1618         default:
1619                 break;
1620         }
1621
1622         return NOTIFICATION_ERROR_NONE;
1623 }
1624
1625 EXPORT_API notification_error_e notification_get_execute_option(notification_h noti,
1626                                                                 notification_execute_type_e type,
1627                                                                 const char **text,
1628                                                                 bundle **service_handle)
1629 {
1630         char buf_key[32] = { 0, };
1631         const char *ret_val = NULL;
1632         char *get_str = NULL;
1633         bundle *b = NULL;
1634
1635         if (noti == NULL) {
1636                 return NOTIFICATION_ERROR_INVALID_DATA;
1637         }
1638
1639         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
1640             || type >= NOTIFICATION_EXECUTE_TYPE_MAX) {
1641                 return NOTIFICATION_ERROR_INVALID_DATA;
1642         }
1643
1644         switch (type) {
1645         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
1646                 b = noti->b_service_responding;
1647                 break;
1648         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
1649                 b = noti->b_service_single_launch;
1650                 break;
1651         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
1652                 b = noti->b_service_multi_launch;
1653                 break;
1654         default:
1655                 b = NULL;
1656                 break;
1657         }
1658
1659         if (b != NULL) {
1660                 // Return text
1661                 if (text != NULL) {
1662                         // Get text domain and dir
1663                         if (noti->domain == NULL || noti->dir == NULL) {
1664                                 _notification_get_text_domain(noti);
1665                         }
1666
1667                         /* Make key */
1668                         snprintf(buf_key, sizeof(buf_key), "key%d", type);
1669
1670                         /* Check key key exist */
1671                         ret_val = bundle_get_val(b, buf_key);
1672                         if (ret_val != NULL && noti->domain != NULL
1673                             && noti->dir != NULL) {
1674                                 /* Get application string */
1675                                 bindtextdomain(noti->domain, noti->dir);
1676
1677                                 get_str = dgettext(noti->domain, ret_val);
1678
1679                                 *text = get_str;
1680                         } else if (ret_val != NULL) {
1681                                 /* Get system string */
1682                                 get_str = dgettext("sys_string", ret_val);
1683
1684                                 *text = get_str;
1685                         } else {
1686                                 /* Get basic text */
1687                                 snprintf(buf_key, sizeof(buf_key), "text%d",
1688                                          type);
1689
1690                                 ret_val = bundle_get_val(b, buf_key);
1691
1692                                 *text = ret_val;
1693                         }
1694                 }
1695         }
1696
1697         switch (type) {
1698         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
1699                 b = noti->b_service_responding;
1700                 break;
1701         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
1702                 b = noti->b_service_single_launch;
1703                 break;
1704         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
1705                 b = noti->b_service_multi_launch;
1706                 break;
1707         default:
1708                 b = NULL;
1709                 break;
1710         }
1711
1712         if (service_handle != NULL) {
1713                 *service_handle = b;
1714         }
1715
1716         return NOTIFICATION_ERROR_NONE;
1717 }
1718
1719 EXPORT_API notification_error_e notification_set_property(notification_h noti,
1720                                                           int flags)
1721 {
1722         /* Check noti is valid data */
1723         if (noti == NULL) {
1724                 return NOTIFICATION_ERROR_INVALID_DATA;
1725         }
1726
1727         /* Set flags */
1728         noti->flags_for_property = flags;
1729
1730         return NOTIFICATION_ERROR_NONE;
1731 }
1732
1733 EXPORT_API notification_error_e notification_get_property(notification_h noti,
1734                                                           int *flags)
1735 {
1736         /* Check noti and flags are valid data */
1737         if (noti == NULL || flags == NULL) {
1738                 return NOTIFICATION_ERROR_INVALID_DATA;
1739         }
1740
1741         /* Set flags */
1742         *flags = noti->flags_for_property;
1743
1744         return NOTIFICATION_ERROR_NONE;
1745 }
1746
1747 EXPORT_API notification_error_e notification_set_display_applist(notification_h noti,
1748                                                                  int applist)
1749 {
1750         /* Check noti is valid data */
1751         if (noti == NULL) {
1752                 return NOTIFICATION_ERROR_INVALID_DATA;
1753         }
1754
1755         /* Set app list */
1756         noti->display_applist = applist;
1757
1758         return NOTIFICATION_ERROR_NONE;
1759 }
1760
1761 EXPORT_API notification_error_e notification_get_display_applist(notification_h noti,
1762                                                                  int *applist)
1763 {
1764         /* Check noti and applist are valid data */
1765         if (noti == NULL || applist == NULL) {
1766                 return NOTIFICATION_ERROR_INVALID_DATA;
1767         }
1768
1769         /* Set app list */
1770         *applist = noti->display_applist;
1771
1772         return NOTIFICATION_ERROR_NONE;
1773 }
1774
1775 EXPORT_API notification_error_e notification_set_size(notification_h noti,
1776                                                       double size)
1777 {
1778         /* Check noti is valid data */
1779         if (noti == NULL) {
1780                 return NOTIFICATION_ERROR_INVALID_DATA;
1781         }
1782
1783         /* Save progress size */
1784         noti->progress_size = size;
1785
1786         return NOTIFICATION_ERROR_NONE;
1787 }
1788
1789 EXPORT_API notification_error_e notification_get_size(notification_h noti,
1790                                                       double *size)
1791 {
1792         /* Check noti and size is valid data */
1793         if (noti == NULL || size == NULL) {
1794                 return NOTIFICATION_ERROR_INVALID_DATA;
1795         }
1796
1797         /* Set progress size */
1798         *size = noti->progress_size;
1799
1800         return NOTIFICATION_ERROR_NONE;
1801 }
1802
1803 EXPORT_API notification_error_e notification_set_progress(notification_h noti,
1804                                                           double percentage)
1805 {
1806         /* Check noti is valid data */
1807         if (noti == NULL) {
1808                 return NOTIFICATION_ERROR_INVALID_DATA;
1809         }
1810
1811         /* Save progress percentage */
1812         noti->progress_percentage = percentage;
1813
1814         return NOTIFICATION_ERROR_NONE;
1815 }
1816
1817 EXPORT_API notification_error_e notification_get_progress(notification_h noti,
1818                                                           double *percentage)
1819 {
1820         /* Check noti and percentage are valid data */
1821         if (noti == NULL || percentage == NULL) {
1822                 return NOTIFICATION_ERROR_INVALID_DATA;
1823         }
1824
1825         /* Set progress percentage */
1826         *percentage = noti->progress_percentage;
1827
1828         return NOTIFICATION_ERROR_NONE;
1829 }
1830
1831 EXPORT_API notification_error_e notification_set_pkgname(notification_h noti,
1832                                                          const char *pkgname)
1833 {
1834         /* check noti and pkgname are valid data */
1835         if (noti == NULL || pkgname == NULL) {
1836                 return NOTIFICATION_ERROR_INVALID_DATA;
1837         }
1838
1839         /* Remove previous caller pkgname */
1840         if (noti->caller_pkgname) {
1841                 free(noti->caller_pkgname);
1842                 noti->caller_pkgname = NULL;
1843         }
1844
1845         noti->caller_pkgname = strdup(pkgname);
1846
1847         return NOTIFICATION_ERROR_NONE;
1848 }
1849
1850 EXPORT_API notification_error_e notification_get_pkgname(notification_h noti,
1851                                                          char **pkgname)
1852 {
1853         /* Check noti and pkgname are valid data */
1854         if (noti == NULL || pkgname == NULL) {
1855                 return NOTIFICATION_ERROR_INVALID_DATA;
1856         }
1857
1858         /* Get caller pkgname */
1859         if (noti->caller_pkgname) {
1860                 *pkgname = noti->caller_pkgname;
1861         } else {
1862                 *pkgname = NULL;
1863         }
1864
1865         return NOTIFICATION_ERROR_NONE;
1866 }
1867
1868 EXPORT_API notification_error_e notification_set_badge(const char *pkgname,
1869                                                        int group_id, int count)
1870 {
1871         char *caller_pkgname = NULL;
1872         int ret = NOTIFICATION_ERROR_NONE;
1873
1874         /* Check count is valid count */
1875         if (count < 0) {
1876                 return NOTIFICATION_ERROR_INVALID_DATA;
1877         }
1878
1879         /* Check pkgname */
1880         if (pkgname == NULL) {
1881                 caller_pkgname = _notification_get_pkgname_by_pid();
1882
1883                 /* Set count into Group DB */
1884                 ret =
1885                     notification_group_set_badge(caller_pkgname, group_id,
1886                                                  count);
1887
1888                 if (caller_pkgname != NULL) {
1889                         free(caller_pkgname);
1890                 }
1891         } else {
1892                 /* Set count into Group DB */
1893                 ret = notification_group_set_badge(pkgname, group_id, count);
1894         }
1895
1896         return ret;
1897 }
1898
1899 EXPORT_API notification_error_e notification_get_badge(const char *pkgname,
1900                                                        int group_id, int *count)
1901 {
1902         char *caller_pkgname = NULL;
1903         int ret = NOTIFICATION_ERROR_NONE;
1904         int ret_unread_count = 0;
1905
1906         /* Check pkgname */
1907         if (pkgname == NULL) {
1908                 caller_pkgname = _notification_get_pkgname_by_pid();
1909
1910                 /* Get count from Group DB */
1911                 ret =
1912                     notification_group_get_badge(caller_pkgname, group_id,
1913                                                  &ret_unread_count);
1914
1915                 if (caller_pkgname != NULL) {
1916                         free(caller_pkgname);
1917                 }
1918         } else {
1919                 /* Get count from Group DB */
1920                 ret =
1921                     notification_group_get_badge(pkgname, group_id,
1922                                                  &ret_unread_count);
1923         }
1924
1925         if (ret != NOTIFICATION_ERROR_NONE) {
1926                 return ret;
1927         }
1928
1929         /* Set count */
1930         if (count != NULL) {
1931                 *count = ret_unread_count;
1932         }
1933
1934         return NOTIFICATION_ERROR_NONE;
1935 }
1936
1937 EXPORT_API notification_error_e notification_get_id(notification_h noti,
1938                                                     int *group_id, int *priv_id)
1939 {
1940         /* check noti is valid data */
1941         if (noti == NULL) {
1942                 return NOTIFICATION_ERROR_INVALID_DATA;
1943         }
1944
1945         /* Check group_id is valid data */
1946         if (group_id) {
1947                 /* Set group id */
1948                 if (noti->group_id < NOTIFICATION_GROUP_ID_NONE) {
1949                         *group_id = NOTIFICATION_GROUP_ID_NONE;
1950                 } else {
1951                         *group_id = noti->group_id;
1952                 }
1953         }
1954
1955         /* Check priv_id is valid data */
1956         if (priv_id) {
1957                 /* Set priv_id */
1958                 *priv_id = noti->priv_id;
1959         }
1960
1961         return NOTIFICATION_ERROR_NONE;
1962 }
1963
1964 EXPORT_API notification_error_e notification_get_type(notification_h noti,
1965                                                       notification_type_e *type)
1966 {
1967         /* Check noti and type is valid data */
1968         if (noti == NULL || type == NULL) {
1969                 return NOTIFICATION_ERROR_INVALID_DATA;
1970         }
1971
1972         /* Set noti type */
1973         *type = noti->type;
1974
1975         return NOTIFICATION_ERROR_NONE;
1976 }
1977
1978 EXPORT_API notification_error_e notification_insert(notification_h noti,
1979                                                     int *priv_id)
1980 {
1981         int ret = 0;
1982
1983         /* Check noti is vaild data */
1984         if (noti == NULL) {
1985                 return NOTIFICATION_ERROR_INVALID_DATA;
1986         }
1987
1988         /* Check noti type is valid type */
1989         if (noti->type <= NOTIFICATION_TYPE_NONE
1990             || noti->type >= NOTIFICATION_TYPE_MAX) {
1991                 return NOTIFICATION_ERROR_INVALID_DATA;
1992         }
1993
1994         /* Save insert time */
1995         noti->insert_time = time(NULL);
1996
1997         /* Insert into DB */
1998         ret = notification_noti_insert(noti);
1999         if (ret != NOTIFICATION_ERROR_NONE) {
2000                 return ret;
2001         }
2002
2003         /* Check disable update on insert property */
2004         if (noti->flags_for_property
2005                 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
2006                 /* Disable changed cb */
2007         } else {
2008                 /* Enable changed cb */
2009                 _notification_changed(NOTI_CHANGED_NOTI);
2010         }
2011
2012         /* If priv_id is valid data, set priv_id */
2013         if (priv_id != NULL) {
2014                 *priv_id = noti->priv_id;
2015         }
2016
2017         return NOTIFICATION_ERROR_NONE;
2018 }
2019
2020 EXPORT_API notification_error_e notification_update(notification_h noti)
2021 {
2022         int ret = 0;
2023
2024         /* Check noti is valid data */
2025         if (noti != NULL) {
2026                 /* Update insert time ? */
2027                 noti->insert_time = time(NULL);
2028
2029                 ret = notification_noti_update(noti);
2030                 if (ret != NOTIFICATION_ERROR_NONE) {
2031                         return ret;
2032                 }
2033         }
2034
2035         /* Send changed notification */
2036         _notification_changed(NOTI_CHANGED_NOTI);
2037
2038         return NOTIFICATION_ERROR_NONE;
2039 }
2040
2041 EXPORT_API notification_error_e notifiation_clear(notification_type_e type)
2042 {
2043         int ret = 0;
2044
2045         /* Delete all notification of type */
2046         ret = notification_noti_delete_all(type, NULL);
2047         if (ret != NOTIFICATION_ERROR_NONE) {
2048                 return ret;
2049         }
2050
2051         /* Send chagned notification */
2052         _notification_changed(NOTI_CHANGED_NOTI);
2053
2054         return NOTIFICATION_ERROR_NONE;
2055 }
2056
2057 EXPORT_API notification_error_e notification_delete_all_by_type(const char *pkgname,
2058                                                                 notification_type_e type)
2059 {
2060         int ret = 0;
2061         char *caller_pkgname = NULL;
2062
2063         if (pkgname == NULL) {
2064                 caller_pkgname = _notification_get_pkgname_by_pid();
2065         } else {
2066                 caller_pkgname = strdup(pkgname);
2067         }
2068
2069         ret = notification_noti_delete_all(type, caller_pkgname);
2070         if (ret != NOTIFICATION_ERROR_NONE) {
2071                 free(caller_pkgname);
2072                 return ret;
2073         }
2074
2075         _notification_changed(NOTI_CHANGED_NOTI);
2076
2077         free(caller_pkgname);
2078
2079         return ret;
2080 }
2081
2082 EXPORT_API notification_error_e notification_delete_group_by_group_id(const char *pkgname,
2083                                                                       notification_type_e type,
2084                                                                       int group_id)
2085 {
2086         int ret = 0;
2087         char *caller_pkgname = NULL;
2088
2089         if (group_id < NOTIFICATION_GROUP_ID_NONE) {
2090                 return NOTIFICATION_ERROR_INVALID_DATA;
2091         }
2092
2093         if (pkgname == NULL) {
2094                 caller_pkgname = _notification_get_pkgname_by_pid();
2095         } else {
2096                 caller_pkgname = strdup(pkgname);
2097         }
2098
2099         ret =
2100             notification_noti_delete_group_by_group_id(caller_pkgname,
2101                                                        group_id);
2102         if (ret != NOTIFICATION_ERROR_NONE) {
2103                 free(caller_pkgname);
2104                 return ret;
2105         }
2106
2107         _notification_changed(NOTI_CHANGED_NOTI);
2108
2109         free(caller_pkgname);
2110
2111         return ret;
2112 }
2113
2114 EXPORT_API notification_error_e notification_delete_group_by_priv_id(const char *pkgname,
2115                                                                      notification_type_e type,
2116                                                                      int priv_id)
2117 {
2118         int ret = 0;
2119         char *caller_pkgname = NULL;
2120
2121         if (priv_id < NOTIFICATION_PRIV_ID_NONE) {
2122                 return NOTIFICATION_ERROR_INVALID_DATA;
2123         }
2124
2125         if (pkgname == NULL) {
2126                 caller_pkgname = _notification_get_pkgname_by_pid();
2127         } else {
2128                 caller_pkgname = strdup(pkgname);
2129         }
2130
2131         ret =
2132             notification_noti_delete_group_by_priv_id(caller_pkgname, priv_id);
2133         if (ret != NOTIFICATION_ERROR_NONE) {
2134                 free(caller_pkgname);
2135                 return ret;
2136         }
2137
2138         _notification_changed(NOTI_CHANGED_NOTI);
2139
2140         free(caller_pkgname);
2141
2142         return ret;
2143 }
2144
2145 EXPORT_API notification_error_e notification_delete_by_priv_id(const char *pkgname,
2146                                                                notification_type_e type,
2147                                                                int priv_id)
2148 {
2149         int ret = 0;
2150         char *caller_pkgname = NULL;
2151
2152         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
2153                 return NOTIFICATION_ERROR_INVALID_DATA;
2154         }
2155
2156         if (pkgname == NULL) {
2157                 caller_pkgname = _notification_get_pkgname_by_pid();
2158         } else {
2159                 caller_pkgname = strdup(pkgname);
2160         }
2161
2162         ret = notification_noti_delete_by_priv_id(caller_pkgname, priv_id);
2163         if (ret != NOTIFICATION_ERROR_NONE) {
2164                 free(caller_pkgname);
2165                 return ret;
2166         }
2167
2168         _notification_changed(NOTI_CHANGED_NOTI);
2169
2170         free(caller_pkgname);
2171
2172         return ret;
2173 }
2174
2175 EXPORT_API notification_error_e notification_delete(notification_h noti)
2176 {
2177         int ret = 0;
2178
2179         if (noti == NULL) {
2180                 return NOTIFICATION_ERROR_INVALID_DATA;
2181         }
2182
2183         ret =
2184             notification_noti_delete_by_priv_id(noti->caller_pkgname,
2185                                                 noti->priv_id);
2186         if (ret != NOTIFICATION_ERROR_NONE) {
2187                 return ret;
2188         }
2189
2190         if (noti->flags_for_property
2191                 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_DELETE) {
2192                 NOTIFICATION_INFO("Disabled update while delete.");
2193         } else {
2194                 _notification_changed(NOTI_CHANGED_NOTI);
2195         }
2196
2197         return NOTIFICATION_ERROR_NONE;
2198 }
2199
2200 EXPORT_API notification_error_e notification_update_progress(notification_h noti,
2201                                                              int priv_id,
2202                                                              double progress)
2203 {
2204         char *caller_pkgname = NULL;
2205         int input_priv_id = 0;
2206         double input_progress = 0.0;
2207
2208         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
2209                 if (noti == NULL) {
2210                         return NOTIFICATION_ERROR_INVALID_DATA;
2211                 } else {
2212                         input_priv_id = noti->priv_id;
2213                 }
2214         } else {
2215                 input_priv_id = priv_id;
2216         }
2217
2218         if (noti == NULL) {
2219                 caller_pkgname = _notification_get_pkgname_by_pid();
2220         } else {
2221                 caller_pkgname = strdup(noti->caller_pkgname);
2222         }
2223
2224         if (progress < 0.0) {
2225                 input_progress = 0.0;
2226         } else if (progress > 1.0) {
2227                 input_progress = 1.0;
2228         } else {
2229                 input_progress = progress;
2230         }
2231
2232         notification_ongoing_update_progress(caller_pkgname, input_priv_id,
2233                                              input_progress);
2234
2235         if (caller_pkgname) {
2236                 free(caller_pkgname);
2237         }
2238
2239         return NOTIFICATION_ERROR_NONE;
2240 }
2241
2242 EXPORT_API notification_error_e notification_update_size(notification_h noti,
2243                                                          int priv_id,
2244                                                          double size)
2245 {
2246         char *caller_pkgname = NULL;
2247         int input_priv_id = 0;
2248         double input_size = 0.0;
2249
2250         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
2251                 if (noti == NULL) {
2252                         return NOTIFICATION_ERROR_INVALID_DATA;
2253                 } else {
2254                         input_priv_id = noti->priv_id;
2255                 }
2256         } else {
2257                 input_priv_id = priv_id;
2258         }
2259
2260         if (noti == NULL) {
2261                 caller_pkgname = _notification_get_pkgname_by_pid();
2262         } else {
2263                 caller_pkgname = strdup(noti->caller_pkgname);
2264         }
2265
2266         if (size < 0.0) {
2267                 input_size = 0.0;
2268         } else {
2269                 input_size = size;
2270         }
2271
2272         notification_ongoing_update_size(caller_pkgname, input_priv_id,
2273                                          input_size);
2274
2275         if (caller_pkgname) {
2276                 free(caller_pkgname);
2277         }
2278
2279         return NOTIFICATION_ERROR_NONE;
2280 }
2281
2282 EXPORT_API notification_error_e notification_update_content(notification_h noti,
2283                                                          int priv_id,
2284                                                          const char *content)
2285 {
2286         char *caller_pkgname = NULL;
2287         int input_priv_id = 0;
2288
2289         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
2290                 if (noti == NULL) {
2291                         return NOTIFICATION_ERROR_INVALID_DATA;
2292                 } else {
2293                         input_priv_id = noti->priv_id;
2294                 }
2295         } else {
2296                 input_priv_id = priv_id;
2297         }
2298
2299         if (noti == NULL) {
2300                 caller_pkgname = _notification_get_pkgname_by_pid();
2301         } else {
2302                 caller_pkgname = strdup(noti->caller_pkgname);
2303         }
2304
2305         notification_ongoing_update_content(caller_pkgname, input_priv_id,
2306                                          content);
2307
2308         if (caller_pkgname) {
2309                 free(caller_pkgname);
2310         }
2311
2312         return NOTIFICATION_ERROR_NONE;
2313 }
2314
2315 EXPORT_API notification_h notification_new(notification_type_e type,
2316                                            int group_id, int priv_id)
2317 {
2318         notification_h noti = NULL;
2319
2320         if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX) {
2321                 NOTIFICATION_ERR("INVALID TYPE : %d", type);
2322                 return NULL;
2323         }
2324
2325         if (group_id < NOTIFICATION_GROUP_ID_NONE) {
2326                 NOTIFICATION_ERR("INVALID GROUP ID : %d", group_id);
2327                 return NULL;
2328         }
2329
2330         if (priv_id < NOTIFICATION_PRIV_ID_NONE) {
2331                 NOTIFICATION_ERR("INVALID PRIV ID : %d", priv_id);
2332                 return NULL;
2333         }
2334
2335         noti = (notification_h) malloc(sizeof(struct _notification));
2336         if (noti == NULL) {
2337                 NOTIFICATION_ERR("NO MEMORY : noti == NULL");
2338                 return NULL;
2339         }
2340         memset(noti, 0x00, sizeof(struct _notification));
2341
2342         noti->type = type;
2343
2344         noti->group_id = group_id;
2345         noti->internal_group_id = 0;
2346         noti->priv_id = priv_id;
2347
2348         noti->caller_pkgname = _notification_get_pkgname_by_pid();
2349         noti->launch_pkgname = NULL;
2350         noti->args = NULL;
2351         noti->group_args = NULL;
2352
2353         noti->b_execute_option = NULL;
2354         noti->b_service_responding = NULL;
2355         noti->b_service_single_launch = NULL;
2356         noti->b_service_multi_launch = NULL;
2357
2358         noti->sound_type = NOTIFICATION_SOUND_TYPE_NONE;
2359         noti->sound_path = NULL;
2360
2361         noti->vibration_type = NOTIFICATION_VIBRATION_TYPE_NONE;
2362         noti->vibration_path = NULL;
2363
2364         noti->domain = NULL;
2365         noti->dir = NULL;
2366
2367         noti->b_text = NULL;
2368         noti->b_key = NULL;
2369         noti->b_format_args = NULL;
2370         noti->num_format_args = 0;
2371
2372         noti->b_image_path = NULL;
2373
2374         noti->time = 0;
2375         noti->insert_time = 0;
2376
2377         noti->flags_for_property = 0;
2378         noti->display_applist = NOTIFICATION_DISPLAY_APP_ALL;
2379
2380         noti->progress_size = 0.0;
2381         noti->progress_percentage = 0.0;
2382
2383         noti->app_icon_path = NULL;
2384         noti->app_name = NULL;
2385         noti->temp_title = NULL;
2386         noti->temp_content = NULL;
2387
2388         return noti;
2389 }
2390
2391 EXPORT_API notification_error_e notification_clone(notification_h noti, notification_h *clone)
2392 {
2393         notification_h new_noti = NULL;
2394
2395         if (noti == NULL || clone == NULL) {
2396                 NOTIFICATION_ERR("INVALID PARAMETER.");
2397                 return NOTIFICATION_ERROR_INVALID_DATA;
2398         }
2399
2400         new_noti = (notification_h) malloc(sizeof(struct _notification));
2401         if (new_noti == NULL) {
2402                 NOTIFICATION_ERR("NO MEMORY : noti == NULL");
2403                 return NOTIFICATION_ERROR_NO_MEMORY;
2404         }
2405         memset(new_noti, 0x00, sizeof(struct _notification));
2406
2407         new_noti->type = noti->type;
2408
2409         new_noti->group_id = noti->group_id;
2410         new_noti->internal_group_id = noti->internal_group_id;
2411         new_noti->priv_id = noti->priv_id;
2412
2413         if(noti->caller_pkgname != NULL) {
2414                 new_noti->caller_pkgname = strdup(noti->caller_pkgname);
2415         } else {
2416                 new_noti->caller_pkgname = _notification_get_pkgname_by_pid();
2417         }
2418         if(noti->launch_pkgname != NULL) {
2419                 new_noti->launch_pkgname = strdup(noti->launch_pkgname);
2420         } else {
2421                 new_noti->launch_pkgname = NULL;
2422         }
2423
2424         if(noti->args != NULL) {
2425                 new_noti->args = bundle_dup(noti->args);
2426         } else {
2427                 new_noti->args = NULL;
2428         }
2429         if(noti->group_args != NULL) {
2430                 new_noti->group_args = bundle_dup(noti->group_args);
2431         } else {
2432                 new_noti->group_args = NULL;
2433         }
2434
2435         if(noti->b_execute_option != NULL) {
2436                 new_noti->b_execute_option = bundle_dup(noti->b_execute_option);
2437         } else {
2438                 new_noti->b_execute_option = NULL;
2439         }
2440         if(noti->b_service_responding != NULL) {
2441                 new_noti->b_service_responding = bundle_dup(noti->b_service_responding);
2442         } else {
2443                 new_noti->b_service_responding = NULL;
2444         }
2445         if(noti->b_service_single_launch != NULL) {
2446                 new_noti->b_service_single_launch = bundle_dup(noti->b_service_single_launch);
2447         } else {
2448                 new_noti->b_service_single_launch = NULL;
2449         }
2450         if(noti->b_service_multi_launch != NULL) {
2451                 new_noti->b_service_multi_launch = bundle_dup(noti->b_service_multi_launch);
2452         } else {
2453                 new_noti->b_service_multi_launch = NULL;
2454         }
2455
2456         new_noti->sound_type = noti->sound_type;
2457         if(noti->sound_path != NULL) {
2458                 new_noti->sound_path = strdup(noti->sound_path);
2459         } else {
2460                 new_noti->sound_path = NULL;
2461         }
2462         new_noti->vibration_type = noti->vibration_type;
2463         if(noti->vibration_path != NULL) {
2464                 new_noti->vibration_path = strdup(noti->vibration_path);
2465         } else {
2466                 new_noti->vibration_path = NULL;
2467         }
2468
2469         if(noti->domain != NULL) {
2470                 new_noti->domain = strdup(noti->domain);
2471         } else {
2472                 new_noti->domain = NULL;
2473         }
2474         if(noti->dir != NULL) {
2475                 new_noti->dir = strdup(noti->dir);
2476         } else {
2477                 new_noti->dir = NULL;
2478         }
2479
2480         if(noti->b_text != NULL) {
2481                 new_noti->b_text = bundle_dup(noti->b_text);
2482         } else {
2483                 new_noti->b_text = NULL;
2484         }
2485         if(noti->b_key != NULL) {
2486                 new_noti->b_key = bundle_dup(noti->b_key);
2487         } else {
2488                 new_noti->b_key = NULL;
2489         }
2490         if(noti->b_format_args != NULL) {
2491                 new_noti->b_format_args = bundle_dup(noti->b_format_args);
2492         } else {
2493                 new_noti->b_format_args = NULL;
2494         }
2495         new_noti->num_format_args = noti->num_format_args;
2496
2497         if(noti->b_image_path != NULL) {
2498                 new_noti->b_image_path = bundle_dup(noti->b_image_path);
2499         } else {
2500                 new_noti->b_image_path = NULL;
2501         }
2502
2503         new_noti->time = noti->time;
2504         new_noti->insert_time = noti->insert_time;
2505
2506         new_noti->flags_for_property = noti->flags_for_property;
2507         new_noti->display_applist = noti->display_applist;
2508
2509         new_noti->progress_size = noti->progress_size;
2510         new_noti->progress_percentage = noti->progress_percentage;
2511
2512         new_noti->app_icon_path = NULL;
2513         new_noti->app_name = NULL;
2514         new_noti->temp_title = NULL;
2515         new_noti->temp_content = NULL;
2516
2517         *clone = new_noti;
2518
2519         return NOTIFICATION_ERROR_NONE;
2520 }
2521
2522
2523 EXPORT_API notification_error_e notification_free(notification_h noti)
2524 {
2525         if (noti == NULL) {
2526                 return NOTIFICATION_ERROR_INVALID_DATA;
2527         }
2528
2529         if (noti->caller_pkgname) {
2530                 free(noti->caller_pkgname);
2531         }
2532         if (noti->launch_pkgname) {
2533                 free(noti->launch_pkgname);
2534         }
2535         if (noti->args) {
2536                 bundle_free(noti->args);
2537         }
2538         if (noti->group_args) {
2539                 bundle_free(noti->group_args);
2540         }
2541
2542         if (noti->b_execute_option) {
2543                 bundle_free(noti->b_execute_option);
2544         }
2545         if (noti->b_service_responding) {
2546                 bundle_free(noti->b_service_responding);
2547         }
2548         if (noti->b_service_single_launch) {
2549                 bundle_free(noti->b_service_single_launch);
2550         }
2551         if (noti->b_service_multi_launch) {
2552                 bundle_free(noti->b_service_multi_launch);
2553         }
2554
2555         if (noti->sound_path) {
2556                 free(noti->sound_path);
2557         }
2558         if (noti->vibration_path) {
2559                 free(noti->vibration_path);
2560         }
2561
2562         if (noti->domain) {
2563                 free(noti->domain);
2564         }
2565         if (noti->dir) {
2566                 free(noti->dir);
2567         }
2568
2569         if (noti->b_text) {
2570                 bundle_free(noti->b_text);
2571         }
2572         if (noti->b_key) {
2573                 bundle_free(noti->b_key);
2574         }
2575         if (noti->b_format_args) {
2576                 bundle_free(noti->b_format_args);
2577         }
2578
2579         if (noti->b_image_path) {
2580                 bundle_free(noti->b_image_path);
2581         }
2582
2583         if (noti->app_icon_path) {
2584                 free(noti->app_icon_path);
2585         }
2586         if (noti->app_name) {
2587                 free(noti->app_name);
2588         }
2589         if (noti->temp_title) {
2590                 free(noti->temp_title);
2591         }
2592         if (noti->temp_content) {
2593                 free(noti->temp_content);
2594         }
2595
2596         free(noti);
2597
2598         return NOTIFICATION_ERROR_NONE;
2599 }
2600
2601 EXPORT_API notification_error_e
2602 notification_resister_changed_cb(void (*changed_cb)
2603                                  (void *data, notification_type_e type),
2604                                  void *user_data)
2605 {
2606         notification_cb_list_s *noti_cb_list_new = NULL;
2607         notification_cb_list_s *noti_cb_list = NULL;
2608
2609         if (!g_dbus_handle) {
2610                 g_dbus_handle = _noti_changed_monitor_init();
2611                 if (!g_dbus_handle)
2612                         return NOTIFICATION_ERROR_FROM_DBUS;
2613         }
2614
2615         noti_cb_list_new =
2616             (notification_cb_list_s *) malloc(sizeof(notification_cb_list_s));
2617
2618         noti_cb_list_new->next = NULL;
2619         noti_cb_list_new->prev = NULL;
2620
2621         noti_cb_list_new->changed_cb = changed_cb;
2622         noti_cb_list_new->data = user_data;
2623
2624         if (g_notification_cb_list == NULL) {
2625                 g_notification_cb_list = noti_cb_list_new;
2626         } else {
2627                 noti_cb_list = g_notification_cb_list;
2628
2629                 while (noti_cb_list->next != NULL) {
2630                         noti_cb_list = noti_cb_list->next;
2631                 }
2632
2633                 noti_cb_list->next = noti_cb_list_new;
2634                 noti_cb_list_new->prev = noti_cb_list;
2635         }
2636         return NOTIFICATION_ERROR_NONE;
2637 }
2638
2639 EXPORT_API notification_error_e
2640 notification_unresister_changed_cb(void (*changed_cb)
2641                                    (void *data, notification_type_e type))
2642 {
2643         notification_cb_list_s *noti_cb_list = NULL;
2644         notification_cb_list_s *noti_cb_list_prev = NULL;
2645         notification_cb_list_s *noti_cb_list_next = NULL;
2646
2647         noti_cb_list = g_notification_cb_list;
2648
2649         if (noti_cb_list == NULL) {
2650                 return NOTIFICATION_ERROR_INVALID_DATA;
2651         }
2652
2653         while (noti_cb_list->prev != NULL) {
2654                 noti_cb_list = noti_cb_list->prev;
2655         }
2656
2657         do {
2658                 if (noti_cb_list->changed_cb == changed_cb) {
2659                         noti_cb_list_prev = noti_cb_list->prev;
2660                         noti_cb_list_next = noti_cb_list->next;
2661
2662                         if (noti_cb_list_prev == NULL) {
2663                                 g_notification_cb_list = noti_cb_list_next;
2664                         } else {
2665                                 noti_cb_list_prev->next = noti_cb_list_next;
2666                         }
2667
2668                         if (noti_cb_list_next == NULL) {
2669                                 if (noti_cb_list_prev != NULL) {
2670                                         noti_cb_list_prev->next = NULL;
2671                                 }
2672                         } else {
2673                                 noti_cb_list_next->prev = noti_cb_list_prev;
2674                         }
2675
2676                         free(noti_cb_list);
2677
2678                         if (g_notification_cb_list == NULL)
2679                                 _noti_chanaged_monitor_fini();
2680
2681                         return NOTIFICATION_ERROR_NONE;
2682                 }
2683                 noti_cb_list = noti_cb_list->next;
2684         } while (noti_cb_list != NULL);
2685
2686         return NOTIFICATION_ERROR_INVALID_DATA;
2687 }
2688
2689 EXPORT_API notification_error_e
2690 notification_resister_badge_changed_cb(void (*changed_cb)
2691                                        (void *data, const char *pkgname,
2692                                         int group_id), void *user_data)
2693 {
2694         // Add DBus signal handler
2695         return NOTIFICATION_ERROR_NONE;
2696 }
2697
2698 EXPORT_API notification_error_e
2699 notification_unresister_badge_changed_cb(void (*changed_cb)
2700                                          (void *data, const char *pkgname,
2701                                           int group_id))
2702 {
2703         // Del DBus signal handler
2704         return NOTIFICATION_ERROR_NONE;
2705 }
2706
2707 EXPORT_API notification_error_e notification_get_count(notification_type_e type,
2708                                                        const char *pkgname,
2709                                                        int group_id,
2710                                                        int priv_id, int *count)
2711 {
2712         int ret = 0;
2713         int noti_count = 0;
2714
2715         ret =
2716             notification_noti_get_count(type, pkgname, group_id, priv_id,
2717                                         &noti_count);
2718         if (ret != NOTIFICATION_ERROR_NONE) {
2719                 return ret;
2720         }
2721
2722         if (count != NULL) {
2723                 *count = noti_count;
2724         }
2725
2726         return NOTIFICATION_ERROR_NONE;
2727 }
2728
2729 EXPORT_API notification_error_e notification_get_list(notification_type_e type,
2730                                                       int count,
2731                                                       notification_list_h *list)
2732 {
2733         notification_list_h get_list = NULL;
2734         int ret = 0;
2735
2736         ret = notification_noti_get_grouping_list(type, count, &get_list);
2737         if (ret != NOTIFICATION_ERROR_NONE) {
2738                 return ret;
2739         }
2740
2741         *list = get_list;
2742
2743         return NOTIFICATION_ERROR_NONE;
2744 }
2745
2746 EXPORT_API notification_error_e
2747 notification_get_grouping_list(notification_type_e type, int count,
2748                                notification_list_h * list)
2749 {
2750         notification_list_h get_list = NULL;
2751         int ret = 0;
2752
2753         ret = notification_noti_get_grouping_list(type, count, &get_list);
2754         if (ret != NOTIFICATION_ERROR_NONE) {
2755                 return ret;
2756         }
2757
2758         *list = get_list;
2759
2760         return NOTIFICATION_ERROR_NONE;
2761 }
2762
2763 EXPORT_API notification_error_e notification_get_detail_list(const char *pkgname,
2764                                                              int group_id,
2765                                                              int priv_id,
2766                                                              int count,
2767                                                              notification_list_h *list)
2768 {
2769         notification_list_h get_list = NULL;
2770         int ret = 0;
2771
2772         ret =
2773             notification_noti_get_detail_list(pkgname, group_id, priv_id, count,
2774                                               &get_list);
2775         if (ret != NOTIFICATION_ERROR_NONE) {
2776                 return ret;
2777         }
2778
2779         *list = get_list;
2780
2781         return NOTIFICATION_ERROR_NONE;
2782 }
2783
2784 EXPORT_API notification_error_e notification_free_list(notification_list_h list)
2785 {
2786         notification_list_h cur_list = NULL;
2787         notification_h noti = NULL;
2788
2789         if (list == NULL) {
2790                 NOTIFICATION_ERR("INVALID DATA : list == NULL");
2791                 return NOTIFICATION_ERROR_INVALID_DATA;
2792         }
2793
2794         cur_list = notification_list_get_head(list);
2795
2796         while (cur_list != NULL) {
2797                 noti = notification_list_get_data(cur_list);
2798                 cur_list = notification_list_remove(cur_list, noti);
2799
2800                 notification_free(noti);
2801         }
2802
2803         return NOTIFICATION_ERROR_NONE;
2804 }