Initialize Noti-ex
[platform/core/api/notification.git] / notification / src / notification_internal.c
1 /*
2  * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <libintl.h>
23 #include <dbus/dbus.h>
24 #include <gio/gio.h>
25
26 #include <aul.h>
27 #include <tizen.h>
28 #include <bundle.h>
29 #include <bundle_internal.h>
30 #include <app_control.h>
31 #include <app_control_internal.h>
32 #include <pkgmgr-info.h>
33
34 #include <notification.h>
35 #include <notification_list.h>
36 #include <notification_debug.h>
37 #include <notification_private.h>
38 #include <notification_noti.h>
39 #include <notification_ongoing.h>
40 #include <notification_group.h>
41 #include <notification_ipc.h>
42 #include <notification_internal.h>
43 #include <notification_shared_file.h>
44
45 #define REGULAR_UID_MIN 5000
46
47 typedef struct _notification_cb_info notification_cb_info_s;
48 typedef struct _notification_event_cb_info notification_event_cb_info_s;
49
50 typedef enum __notification_cb_type {
51         NOTIFICATION_CB_NORMAL = 1,
52         NOTIFICATION_CB_DETAILED,
53 } _notification_cb_type_e;
54
55 struct _notification_cb_info {
56         _notification_cb_type_e cb_type;
57         void (*changed_cb)(void *data, notification_type_e type);
58         void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op);
59         void *data;
60 };
61
62 struct _notification_event_cb_info {
63         int priv_id;
64         event_handler_cb cb;
65         void *userdata;
66 };
67
68 static GHashTable *_noti_cb_hash = NULL;
69 static GList *__noti_event_cb_list = NULL;
70
71 void notification_reset_event_handler_list(void)
72 {
73         GList *iter;
74         notification_event_cb_info_s *info;
75
76         if (!__noti_event_cb_list)
77                 return;
78
79         iter = g_list_first(__noti_event_cb_list);
80         while (iter) {
81                 info = g_list_nth_data(iter, 0);
82                 if (info)
83                         notification_ipc_reset_event_handler(info->priv_id);
84                 iter = g_list_next(iter);
85         }
86 }
87
88 /* LCOV_EXCL_START */
89 static void __free_changed_cb_info(gpointer data)
90 {
91         notification_cb_info_s *noti_cb_info = (notification_cb_info_s *)data;
92
93         if (noti_cb_info)
94                 free(noti_cb_info);
95 }
96 /* LCOV_EXCL_STOP */
97
98 void notification_call_changed_cb_for_uid(notification_op *op_list, int op_num, uid_t uid)
99 {
100         notification_type_e type = NOTIFICATION_TYPE_NOTI;
101         GList *noti_cb_list;
102         notification_cb_info_s *noti_cb_info;
103
104         if (_noti_cb_hash == NULL)
105                 return;
106
107         noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
108         if (noti_cb_list == NULL)
109                 return;
110
111         if (op_list == NULL) {
112                 ERR("Invalid parameter");
113                 return;
114         }
115
116         noti_cb_list = g_list_first(noti_cb_list);
117         notification_get_type(op_list->noti, &type);
118
119         for (; noti_cb_list != NULL; noti_cb_list = noti_cb_list->next) {
120                 noti_cb_info = noti_cb_list->data;
121
122                 if (noti_cb_info->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_info->changed_cb)
123                         noti_cb_info->changed_cb(noti_cb_info->data, type);
124
125                 if (noti_cb_info->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_info->detailed_changed_cb) {
126                         noti_cb_info->detailed_changed_cb(noti_cb_info->data,
127                                         type, op_list, op_num);
128                 }
129         }
130 }
131
132 static gint __priv_id_compare(gconstpointer a, gconstpointer b)
133 {
134         const notification_event_cb_info_s *info = NULL;
135
136         if (!a)
137                 return -1;
138
139         info = (notification_event_cb_info_s *)a;
140
141         if (info->priv_id == GPOINTER_TO_INT(b))
142                 return 0;
143
144         return 1;
145 }
146
147 void notification_call_event_handler_cb(notification_h noti, int event_type)
148 {
149         int ret;
150         int priv_id;
151         GList *find_list;
152         notification_event_cb_info_s *info;
153
154         if (__noti_event_cb_list == NULL)
155                 return;
156
157         ret = notification_get_id(noti, NULL, &priv_id);
158         if (ret != NOTIFICATION_ERROR_NONE)
159                 return;
160
161         __noti_event_cb_list = g_list_first(__noti_event_cb_list);
162         find_list = g_list_find_custom(__noti_event_cb_list, GINT_TO_POINTER(priv_id),
163                                        (GCompareFunc)__priv_id_compare);
164         if (find_list == NULL)
165                 return;
166
167         info = g_list_nth_data(find_list, 0);
168         info->cb(noti, event_type, info->userdata);
169 }
170
171 /* LCOV_EXCL_START */
172 void notification_delete_event_handler_cb(int priv_id)
173 {
174         GList *delete_list;
175         notification_event_cb_info_s *info;
176
177         if (__noti_event_cb_list == NULL)
178                 return;
179
180         __noti_event_cb_list = g_list_first(__noti_event_cb_list);
181         delete_list = g_list_find_custom(__noti_event_cb_list, GINT_TO_POINTER(priv_id),
182                                          (GCompareFunc)__priv_id_compare);
183
184         if (delete_list == NULL)
185                 return;
186
187         info = g_list_nth_data(delete_list, 0);
188         __noti_event_cb_list = g_list_remove(g_list_first(__noti_event_cb_list), info);
189
190         if (info)
191                 free(info);
192
193         if (__noti_event_cb_list == NULL)
194                 notification_ipc_event_monitor_fini();
195 }
196 /* LCOV_EXCL_STOP */
197
198 EXPORT_API int notification_add_deferred_task(
199                 void (*deferred_task_cb)(void *data), void *user_data)
200 {
201         if (deferred_task_cb == NULL)
202                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
203
204         return notification_ipc_add_deffered_task(deferred_task_cb, user_data);
205 }
206
207 EXPORT_API int notification_del_deferred_task(
208                 void (*deferred_task_cb)(void *data))
209 {
210         if (deferred_task_cb == NULL)
211                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
212
213         return notification_ipc_del_deffered_task(deferred_task_cb);
214 }
215
216 EXPORT_API int notification_resister_changed_cb_for_uid(
217                 void (*changed_cb)(void *data, notification_type_e type),
218                 void *user_data, uid_t uid)
219 {
220         GList *noti_cb_list;
221         notification_cb_info_s *noti_cb_info_new;
222
223         if (changed_cb == NULL)
224                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
225
226         if (_noti_cb_hash == NULL)
227                 _noti_cb_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
228
229         noti_cb_info_new = (notification_cb_info_s *)malloc(sizeof(notification_cb_info_s));
230         if (noti_cb_info_new == NULL) {
231                 /* LCOV_EXCL_START */
232                 ERR("Failed to alloc memory");
233                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
234                 /* LCOV_EXCL_STOP */
235         }
236
237         noti_cb_info_new->cb_type = NOTIFICATION_CB_NORMAL;
238         noti_cb_info_new->changed_cb = changed_cb;
239         noti_cb_info_new->detailed_changed_cb = NULL;
240         noti_cb_info_new->data = user_data;
241
242         noti_cb_list = g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
243
244         if (noti_cb_list == NULL) {
245                 noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
246                 g_hash_table_insert(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
247         } else {
248                 noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
249         }
250
251         if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE) {
252                 notification_unresister_changed_cb_for_uid(changed_cb, uid);
253                 return NOTIFICATION_ERROR_IO_ERROR;
254         }
255
256         return NOTIFICATION_ERROR_NONE;
257 }
258
259 EXPORT_API int notification_resister_changed_cb(
260                 void (*changed_cb)(void *data, notification_type_e type),
261                 void *user_data)
262 {
263         return notification_resister_changed_cb_for_uid(changed_cb, user_data, getuid());
264 }
265
266 static gint _noti_changed_compare(gconstpointer a, gconstpointer b)
267 {
268         const struct _notification_cb_info *info = NULL;
269
270         if (!a)
271                 return -1;
272         info = (notification_cb_info_s *)a;
273
274         if (info->changed_cb == b)
275                 return 0;
276
277         return 1;
278 }
279
280 EXPORT_API int notification_unresister_changed_cb_for_uid(
281                 void (*changed_cb)(void *data, notification_type_e type), uid_t uid)
282 {
283         notification_cb_info_s *noti_cb_info;
284         GList *noti_cb_list;
285         GList *delete_cb_list;
286
287         if (changed_cb == NULL)
288                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
289
290         if (_noti_cb_hash == NULL)
291                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
292
293         noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
294         if (noti_cb_list == NULL)
295                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
296
297         noti_cb_list = g_list_first(noti_cb_list);
298         delete_cb_list = g_list_find_custom(noti_cb_list, (gconstpointer)changed_cb,
299                                             (GCompareFunc)_noti_changed_compare);
300         if (delete_cb_list) {
301                 noti_cb_info = g_list_nth_data(delete_cb_list, 0);
302                 noti_cb_list = g_list_delete_link(noti_cb_list, delete_cb_list);
303                 __free_changed_cb_info(noti_cb_info);
304
305                 if (noti_cb_list == NULL) {
306                         g_hash_table_steal(_noti_cb_hash, GUINT_TO_POINTER(uid));
307                 } else {
308                         noti_cb_list = g_list_first(noti_cb_list);
309                         g_hash_table_replace(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
310                 }
311
312         } else {
313                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
314         }
315
316         if (g_hash_table_size(_noti_cb_hash) == 0)
317                 notification_ipc_monitor_fini();
318
319         return NOTIFICATION_ERROR_NONE;
320 }
321
322 EXPORT_API int notification_unresister_changed_cb(
323                 void (*changed_cb)(void *data, notification_type_e type))
324 {
325         return notification_unresister_changed_cb_for_uid(changed_cb, getuid());
326 }
327
328 EXPORT_API int notification_update_progress(notification_h noti,
329                 int priv_id,
330                 double progress)
331 {
332         int ret;
333         int input_priv_id;
334         char *caller_app_id;
335         double input_progress;
336
337         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
338                 if (noti == NULL)
339                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
340
341                 input_priv_id = noti->priv_id;
342         } else {
343                 input_priv_id = priv_id;
344         }
345
346         if (noti == NULL)
347                 caller_app_id = notification_get_app_id_by_pid(getpid());
348         else
349                 caller_app_id = strdup(noti->caller_app_id);
350
351         if (progress < 0.0)
352                 input_progress = 0.0;
353         else if (progress > 1.0)
354                 input_progress = 1.0;
355         else
356                 input_progress = progress;
357
358         ret = notification_ongoing_update_progress(caller_app_id, input_priv_id,
359                         input_progress);
360
361         if (caller_app_id)
362                 free(caller_app_id);
363
364         return ret;
365 }
366
367 EXPORT_API int notification_update_size(notification_h noti,
368                 int priv_id,
369                 double size)
370 {
371         int ret;
372         int input_priv_id;
373         char *caller_app_id;
374         double input_size;
375
376         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
377                 if (noti == NULL)
378                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
379
380                 input_priv_id = noti->priv_id;
381         } else {
382                 input_priv_id = priv_id;
383         }
384
385         if (noti == NULL)
386                 caller_app_id = notification_get_app_id_by_pid(getpid());
387         else
388                 caller_app_id = strdup(noti->caller_app_id);
389
390         if (size < 0.0)
391                 input_size = 0.0;
392         else
393                 input_size = size;
394
395         ret = notification_ongoing_update_size(caller_app_id, input_priv_id,
396                         input_size);
397
398         if (caller_app_id)
399                 free(caller_app_id);
400
401         return ret;
402 }
403
404 EXPORT_API int notification_update_content(notification_h noti,
405                 int priv_id,
406                 const char *content)
407 {
408         char *caller_app_id;
409         int input_priv_id;
410         int ret;
411
412         if (priv_id <= NOTIFICATION_PRIV_ID_NONE) {
413                 if (noti == NULL)
414                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
415
416                 input_priv_id = noti->priv_id;
417         } else {
418                 input_priv_id = priv_id;
419         }
420
421         if (noti == NULL)
422                 caller_app_id = notification_get_app_id_by_pid(getpid());
423         else
424                 caller_app_id = strdup(noti->caller_app_id);
425
426         ret = notification_ongoing_update_content(caller_app_id, input_priv_id,
427                         content);
428
429         if (caller_app_id)
430                 free(caller_app_id);
431
432         return ret;
433 }
434
435 /* notification_set_icon will be removed */
436 /* LCOV_EXCL_START */
437 EXPORT_API int notification_set_icon(notification_h noti,
438                 const char *icon_path)
439 {
440         return notification_set_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, icon_path);
441 }
442 /* LCOV_EXCL_STOP */
443
444 /* notification_get_icon will be removed */
445 /* LCOV_EXCL_START */
446 EXPORT_API int notification_get_icon(notification_h noti,
447                 char **icon_path)
448 {
449         int ret = NOTIFICATION_ERROR_NONE;
450         char *ret_image_path = NULL;
451
452         ret = notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON,
453                                 &ret_image_path);
454
455         if (ret == NOTIFICATION_ERROR_NONE && icon_path != NULL)
456                 *icon_path = ret_image_path;
457
458         return ret;
459 }
460 /* LCOV_EXCL_STOP */
461
462 EXPORT_API int notification_translate_localized_text(notification_h noti)
463 {
464         int ret = NOTIFICATION_ERROR_NONE;
465         char *ret_text = NULL;
466         char buf_key[32];
467         char *bundle_val = NULL;
468         char *new_text;
469         bundle *b;
470         notification_text_type_e type = NOTIFICATION_TEXT_TYPE_TITLE;
471
472         noti->is_translation = false;
473
474         for (; type <= NOTIFICATION_TEXT_TYPE_MAX; type++) {
475                 ret = notification_get_text(noti, type, &ret_text);
476                 if (ret == NOTIFICATION_ERROR_NONE && ret_text) {
477                         if (noti->b_text == NULL) {
478                                 noti->b_text = bundle_create();
479                                 if (noti->b_text == NULL)
480                                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
481                         }
482
483                         b = noti->b_text;
484
485                         new_text = strdup(ret_text);
486
487                         snprintf(buf_key, sizeof(buf_key), "%d", type);
488                         bundle_get_str(b, buf_key, &bundle_val);
489                         if (bundle_val != NULL)
490                                 bundle_del(b, buf_key);
491
492                         bundle_add_str(b, buf_key, new_text);
493                         free(new_text);
494                         new_text = NULL;
495
496                         noti->num_format_args = 0;
497                         bundle_val = NULL;
498                 }
499         }
500
501         noti->is_translation = true;
502
503         return ret;
504 }
505
506 /* LCOV_EXCL_START */
507 EXPORT_API int notification_set_title(notification_h noti,
508                 const char *title,
509                 const char *loc_title)
510 {
511         return notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
512                                 title, loc_title,
513                                 NOTIFICATION_VARIABLE_TYPE_NONE);
514 }
515 /* LCOV_EXCL_STOP */
516
517 /* LCOV_EXCL_START */
518 EXPORT_API int notification_get_title(notification_h noti,
519                 char **title,
520                 char **loc_title)
521 {
522         int ret;
523         char *ret_text = NULL;
524
525         ret = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE,
526                                 &ret_text);
527
528         if (title != NULL)
529                 *title = ret_text;
530
531         if (loc_title != NULL)
532                 *loc_title = NULL;
533
534         return ret;
535 }
536 /* LCOV_EXCL_STOP */
537
538 /* LCOV_EXCL_START */
539 EXPORT_API int notification_set_content(notification_h noti,
540                 const char *content,
541                 const char *loc_content)
542 {
543         return notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
544                                 content, loc_content,
545                                 NOTIFICATION_VARIABLE_TYPE_NONE);
546 }
547 /* LCOV_EXCL_STOP */
548
549 /* LCOV_EXCL_START */
550 EXPORT_API int notification_get_content(notification_h noti,
551                 char **content,
552                 char **loc_content)
553 {
554         int ret;
555         char *ret_text = NULL;
556
557         ret = notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
558                                 &ret_text);
559
560         if (content != NULL)
561                 *content = ret_text;
562
563         if (loc_content != NULL)
564                 *loc_content = NULL;
565
566         return ret;
567 }
568 /* LCOV_EXCL_STOP */
569
570 /* LCOV_EXCL_START */
571 EXPORT_API int notification_set_application(notification_h noti,
572                 const char *app_id)
573 {
574         if (noti == NULL || app_id == NULL)
575                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
576
577         if (noti->launch_app_id)
578                 free(noti->launch_app_id);
579
580         noti->launch_app_id = strdup(app_id);
581
582         return NOTIFICATION_ERROR_NONE;
583 }
584 /* LCOV_EXCL_STOP */
585
586 /* LCOV_EXCL_START */
587 EXPORT_API int notification_get_application(notification_h noti,
588                 char **app_id)
589 {
590         if (noti == NULL || app_id == NULL)
591                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
592
593         if (noti->launch_app_id)
594                 *app_id = noti->launch_app_id;
595         else
596                 *app_id = noti->caller_app_id;
597
598         return NOTIFICATION_ERROR_NONE;
599 }
600 /* LCOV_EXCL_STOP */
601
602 /* LCOV_EXCL_START */
603 EXPORT_API int notification_set_args(notification_h noti, bundle *args,
604                 bundle *group_args)
605 {
606         if (noti == NULL || args == NULL)
607                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
608
609         if (noti->args)
610                 bundle_free(noti->args);
611
612         noti->args = bundle_dup(args);
613
614         if (noti->group_args) {
615                 bundle_free(noti->group_args);
616                 noti->group_args = NULL;
617         }
618
619         if (group_args != NULL)
620                 noti->group_args = bundle_dup(group_args);
621
622         return NOTIFICATION_ERROR_NONE;
623 }
624 /* LCOV_EXCL_STOP */
625
626 /* LCOV_EXCL_START */
627 EXPORT_API int notification_get_args(notification_h noti,
628                 bundle **args,
629                 bundle **group_args)
630 {
631         if (noti == NULL || args == NULL)
632                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
633
634         if (noti->args)
635                 *args = noti->args;
636         else
637                 *args = NULL;
638
639         if (group_args != NULL && noti->group_args)
640                 *group_args = noti->group_args;
641
642         return NOTIFICATION_ERROR_NONE;
643 }
644 /* LCOV_EXCL_STOP */
645
646 /* LCOV_EXCL_START */
647 int notification_get_grouping_list_for_uid(notification_type_e type, int count,
648                 notification_list_h *list, uid_t uid)
649 {
650         notification_list_h get_list = NULL;
651         int ret = 0;
652
653         if (list == NULL)
654                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
655
656         ret = notification_noti_get_grouping_list(type, 1, count, &get_list, NULL, uid);
657         if (ret != NOTIFICATION_ERROR_NONE)
658                 return ret;
659
660         *list = get_list;
661
662         return NOTIFICATION_ERROR_NONE;
663 }
664
665 EXPORT_API int notification_get_grouping_list(notification_type_e type, int count,
666                 notification_list_h *list)
667 {
668         return notification_get_grouping_list_for_uid(type, count, list, getuid());
669 }
670 /* LCOV_EXCL_STOP */
671
672 /* LCOV_EXCL_START */
673 EXPORT_API int notification_delete_group_by_group_id(const char *app_id,
674                 notification_type_e type,
675                 int group_id)
676 {
677         int ret;
678         char *caller_app_id;
679
680         if (app_id == NULL)
681                 caller_app_id = notification_get_app_id_by_pid(getpid());
682         else
683                 caller_app_id = strdup(app_id);
684
685         ret = notification_ipc_request_delete_multiple(type, caller_app_id, getuid());
686
687         if (caller_app_id)
688                 free(caller_app_id);
689
690         return ret;
691 }
692 /* LCOV_EXCL_STOP */
693
694 /* LCOV_EXCL_START */
695 int notification_delete_group_by_priv_id_for_uid(const char *app_id,
696                 notification_type_e type,
697                 int priv_id, uid_t uid)
698 {
699         int ret;
700         char *caller_app_id;
701
702         if (app_id == NULL)
703                 caller_app_id = notification_get_app_id_by_pid(getpid());
704         else
705                 caller_app_id = strdup(app_id);
706
707         ret = notification_ipc_request_delete_single(type, caller_app_id, priv_id, uid);
708
709         if (caller_app_id)
710                 free(caller_app_id);
711
712         return ret;
713 }
714 /* LCOV_EXCL_STOP */
715
716 /* LCOV_EXCL_START */
717 EXPORT_API int notification_delete_group_by_priv_id(const char *app_id,
718                 notification_type_e type,
719                 int priv_id)
720 {
721         return notification_delete_group_by_priv_id_for_uid(app_id, type, priv_id, getuid());
722 }
723
724 int notification_get_count_for_uid(notification_type_e type,
725                 const char *app_id,
726                 int group_id,
727                 int priv_id, int *count,
728                 uid_t uid)
729 {
730         int ret;
731         char *caller_app_id;
732
733         if (count == NULL)
734                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
735
736         if (app_id == NULL)
737                 caller_app_id = notification_get_app_id_by_pid(getpid());
738         else
739                 caller_app_id = strdup(app_id);
740
741         ret = notification_ipc_request_get_count(
742                         type,
743                         caller_app_id,
744                         group_id,
745                         priv_id,
746                         count,
747                         uid);
748
749         if (caller_app_id)
750                 free(caller_app_id);
751
752         return ret;
753 }
754 /* LCOV_EXCL_STOP */
755
756 /* LCOV_EXCL_START */
757 EXPORT_API int notification_get_count(notification_type_e type,
758                 const char *app_id,
759                 int group_id,
760                 int priv_id, int *count)
761 {
762         return notification_get_count_for_uid(type, app_id, group_id, priv_id, count, getuid());
763 }
764
765 int notification_clear_for_uid(notification_type_e type, uid_t uid)
766 {
767         if (type <= NOTIFICATION_TYPE_NONE || type > NOTIFICATION_TYPE_MAX)
768                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
769
770         return notification_ipc_request_delete_multiple(type, NULL, uid);
771 }
772 /* LCOV_EXCL_STOP */
773
774 /* LCOV_EXCL_START */
775 EXPORT_API int notification_clear(notification_type_e type)
776 {
777         return notification_clear_for_uid(type, getuid());
778 }
779
780 EXPORT_API int notification_op_get_data(notification_op *noti_op, notification_op_data_type_e type,
781                 void *data)
782 {
783         if (noti_op == NULL || data == NULL)
784                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
785
786         switch (type) {
787         case NOTIFICATION_OP_DATA_TYPE:
788                 *((int *)data) = noti_op->type;
789                 break;
790         case NOTIFICATION_OP_DATA_PRIV_ID:
791                 *((int *)data) = noti_op->priv_id;
792                 break;
793         case NOTIFICATION_OP_DATA_NOTI:
794                 *((notification_h *)data) = noti_op->noti;
795                 break;
796         case NOTIFICATION_OP_DATA_EXTRA_INFO_1:
797                 *((int *)data) = noti_op->extra_info_1;
798                 break;
799         case NOTIFICATION_OP_DATA_EXTRA_INFO_2:
800                 *((int *)data) = noti_op->extra_info_2;
801                 break;
802         default:
803                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
804         }
805
806         return NOTIFICATION_ERROR_NONE;
807 }
808 /* LCOV_EXCL_STOP */
809
810 /* LCOV_EXCL_START */
811 EXPORT_API int notification_set_pkgname(notification_h noti,
812                 const char *pkgname)
813 {
814         return notification_set_app_id(noti, pkgname);
815 }
816 /* LCOV_EXCL_STOP */
817
818 EXPORT_API int notification_set_app_id(notification_h noti,
819                 const char *app_id)
820 {
821         if (noti == NULL || app_id == NULL)
822                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
823
824         /* Remove previous caller app_id */
825         if (noti->caller_app_id) {
826                 free(noti->caller_app_id);
827                 noti->caller_app_id = NULL;
828         }
829
830         noti->caller_app_id = strdup(app_id);
831
832         return NOTIFICATION_ERROR_NONE;
833 }
834
835 /* LCOV_EXCL_START */
836 int notification_delete_all_by_type_for_uid(const char *app_id,
837                 notification_type_e type, uid_t uid)
838 {
839         int ret;
840         char *caller_app_id;
841
842         if (type <= NOTIFICATION_TYPE_NONE || type > NOTIFICATION_TYPE_MAX)
843                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
844
845         if (app_id == NULL)
846                 caller_app_id = notification_get_app_id_by_pid(getpid());
847         else
848                 caller_app_id = strdup(app_id);
849
850         ret = notification_ipc_request_delete_multiple(type, caller_app_id, uid);
851
852         if (caller_app_id)
853                 free(caller_app_id);
854
855         return ret;
856 }
857 /* LCOV_EXCL_STOP */
858
859 /* LCOV_EXCL_START */
860 EXPORT_API int notification_delete_all_by_type(const char *app_id,
861                 notification_type_e type)
862 {
863         return notification_delete_all_by_type_for_uid(app_id, type, getuid());
864 }
865
866 int notification_delete_by_priv_id_for_uid(const char *app_id,
867                 notification_type_e type,
868                 int priv_id,
869                 uid_t uid)
870 {
871         int ret;
872         char *caller_app_id;
873
874         if (priv_id <= NOTIFICATION_PRIV_ID_NONE)
875                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
876
877         if (app_id == NULL)
878                 caller_app_id = notification_get_app_id_by_pid(getpid());
879         else
880                 caller_app_id = strdup(app_id);
881
882         ret = notification_ipc_request_delete_single(type, caller_app_id, priv_id, uid);
883
884         if (caller_app_id)
885                 free(caller_app_id);
886
887         return ret;
888 }
889 /* LCOV_EXCL_STOP */
890
891 /* LCOV_EXCL_START */
892 EXPORT_API int notification_delete_by_priv_id(const char *app_id,
893                 notification_type_e type,
894                 int priv_id)
895 {
896         return notification_delete_by_priv_id_for_uid(app_id, type, priv_id, getuid());
897 }
898
899 EXPORT_API int notification_set_execute_option(notification_h noti,
900                 notification_execute_type_e type,
901                 const char *text,
902                 const char *key,
903                 bundle *service_handle)
904 {
905         char buf_key[32] = { 0, };
906         char *ret_val = NULL;
907         bundle *b = NULL;
908
909         if (noti == NULL)
910                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
911
912         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
913                         || type > NOTIFICATION_EXECUTE_TYPE_MAX)
914                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
915
916         if (noti->b_execute_option == NULL)
917                 noti->b_execute_option = bundle_create();
918
919         b = noti->b_execute_option;
920
921         if (text != NULL) {
922                 snprintf(buf_key, sizeof(buf_key), "text%d", type);
923
924                 bundle_get_str(b, buf_key, &ret_val);
925                 if (ret_val != NULL)
926                         bundle_del(b, buf_key);
927
928                 bundle_add_str(b, buf_key, text);
929         }
930
931         if (key != NULL) {
932                 snprintf(buf_key, sizeof(buf_key), "key%d", type);
933
934                 bundle_get_str(b, buf_key, &ret_val);
935                 if (ret_val != NULL)
936                         bundle_del(b, buf_key);
937
938                 bundle_add_str(b, buf_key, key);
939         }
940
941         switch ((int)type) {
942         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
943                 if (noti->b_service_responding != NULL) {
944                         bundle_free(noti->b_service_responding);
945                         noti->b_service_responding = NULL;
946                 }
947
948                 if (service_handle != NULL)
949                         noti->b_service_responding = bundle_dup(service_handle);
950
951                 break;
952         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
953                 if (noti->b_service_single_launch != NULL) {
954                         bundle_free(noti->b_service_single_launch);
955                         noti->b_service_single_launch = NULL;
956                 }
957
958                 if (service_handle != NULL)
959                         noti->b_service_single_launch =
960                                 bundle_dup(service_handle);
961
962                 break;
963         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
964                 if (noti->b_service_multi_launch != NULL) {
965                         bundle_free(noti->b_service_multi_launch);
966                         noti->b_service_multi_launch = NULL;
967                 }
968
969                 if (service_handle != NULL)
970                         noti->b_service_multi_launch =
971                                 bundle_dup(service_handle);
972
973                 break;
974         }
975
976         return NOTIFICATION_ERROR_NONE;
977 }
978 /* LCOV_EXCL_STOP */
979
980 /* LCOV_EXCL_START */
981 EXPORT_API int notification_get_id(notification_h noti,
982                 int *group_id, int *priv_id)
983 {
984         if (noti == NULL)
985                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
986
987         if (group_id) {
988                 if (noti->group_id < NOTIFICATION_GROUP_ID_NONE)
989                         *group_id = NOTIFICATION_GROUP_ID_NONE;
990                 else
991                         *group_id = noti->group_id;
992         }
993
994         if (priv_id)
995                 *priv_id = noti->priv_id;
996
997         return NOTIFICATION_ERROR_NONE;
998 }
999 /* LCOV_EXCL_STOP */
1000
1001 EXPORT_API int notification_set_priv_id(notification_h noti, int priv_id)
1002 {
1003         if (noti == NULL || priv_id <= 0)
1004                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1005
1006         noti->priv_id = priv_id;
1007
1008         return NOTIFICATION_ERROR_NONE;
1009 }
1010
1011 /* LCOV_EXCL_START */
1012 notification_h notification_load_for_uid(char *app_id,
1013                 int priv_id, uid_t uid)
1014 {
1015         int ret;
1016         notification_h noti;
1017
1018         noti = (notification_h)calloc(1, sizeof(struct _notification));
1019         if (noti == NULL) {
1020                 ERR("Failed to alloc memory");
1021                 set_last_result(NOTIFICATION_ERROR_OUT_OF_MEMORY);
1022                 return NULL;
1023         }
1024
1025         ret = notification_ipc_request_load_noti_by_priv_id(noti, app_id, priv_id, uid);
1026         if (ret != NOTIFICATION_ERROR_NONE) {
1027                 notification_free(noti);
1028                 set_last_result(ret);
1029                 return NULL;
1030         }
1031
1032         set_last_result(NOTIFICATION_ERROR_NONE);
1033
1034         return noti;
1035 }
1036 /* LCOV_EXCL_STOP */
1037
1038 /* LCOV_EXCL_START */
1039 EXPORT_API notification_h notification_load(char *app_id,
1040                 int priv_id)
1041 {
1042         return notification_load_for_uid(app_id, priv_id, getuid());
1043 }
1044 /* LCOV_EXCL_STOP */
1045
1046 /* LCOV_EXCL_START */
1047 EXPORT_API notification_h notification_new(notification_type_e type,
1048                 int group_id, int priv_id)
1049 {
1050         return notification_create(type);
1051 }
1052
1053 static void _notification_get_text_domain(notification_h noti)
1054 {
1055 }
1056 /* LCOV_EXCL_STOP */
1057
1058 /* LCOV_EXCL_START */
1059 EXPORT_API int notification_get_execute_option(notification_h noti,
1060                 notification_execute_type_e type,
1061                 const char **text,
1062                 bundle **service_handle)
1063 {
1064         char buf_key[32] = { 0, };
1065         char *ret_val = NULL;
1066         char *get_str = NULL;
1067         bundle *b = NULL;
1068
1069         if (noti == NULL)
1070                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1071
1072         if (type <= NOTIFICATION_EXECUTE_TYPE_NONE
1073                         || type > NOTIFICATION_EXECUTE_TYPE_MAX)
1074                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1075
1076         switch (type) {
1077         case NOTIFICATION_EXECUTE_TYPE_RESPONDING:
1078                 b = noti->b_service_responding;
1079                 break;
1080         case NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH:
1081                 b = noti->b_service_single_launch;
1082                 break;
1083         case NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH:
1084                 b = noti->b_service_multi_launch;
1085                 break;
1086         default:
1087                 break;
1088         }
1089
1090         if (b != NULL) {
1091                 if (text != NULL) {
1092                         if (noti->domain == NULL || noti->dir == NULL)
1093                                 _notification_get_text_domain(noti);
1094
1095                         snprintf(buf_key, sizeof(buf_key), "key%d", type);
1096
1097                         bundle_get_str(b, buf_key, &ret_val);
1098                         if (ret_val != NULL && noti->domain != NULL
1099                                         && noti->dir != NULL) {
1100                                 bindtextdomain(noti->domain, noti->dir);
1101
1102                                 get_str = dgettext(noti->domain, ret_val);
1103
1104                                 *text = get_str;
1105                         } else if (ret_val != NULL) {
1106                                 get_str = dgettext("sys_string", ret_val);
1107
1108                                 *text = get_str;
1109                         } else {
1110                                 snprintf(buf_key, sizeof(buf_key), "text%d",
1111                                                 type);
1112
1113                                 bundle_get_str(b, buf_key, &ret_val);
1114
1115                                 *text = ret_val;
1116                         }
1117                 }
1118         }
1119
1120         if (service_handle != NULL)
1121                 *service_handle = b;
1122
1123         return NOTIFICATION_ERROR_NONE;
1124 }
1125 /* LCOV_EXCL_STOP */
1126
1127 EXPORT_API int notification_insert_for_uid(notification_h noti,
1128                 int *priv_id, uid_t uid)
1129 {
1130         int ret;
1131         int id;
1132
1133         if (noti == NULL)
1134                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1135
1136         if (noti->type <= NOTIFICATION_TYPE_NONE
1137                         || noti->type > NOTIFICATION_TYPE_MAX)
1138                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1139
1140         noti->uid = uid;
1141         noti->insert_time = time(NULL);
1142
1143         ret = notification_ipc_request_insert(noti, &id);
1144         if (ret != NOTIFICATION_ERROR_NONE)
1145                 return ret;
1146
1147         noti->priv_id = id;
1148
1149         /* If priv_id is valid data, set priv_id */
1150         if (priv_id != NULL)
1151                 *priv_id = noti->priv_id;
1152
1153         return NOTIFICATION_ERROR_NONE;
1154 }
1155
1156 EXPORT_API int notification_insert(notification_h noti,
1157                 int *priv_id)
1158 {
1159         return notification_insert_for_uid(noti, priv_id, getuid());
1160 }
1161
1162 EXPORT_API int notification_update_async_for_uid(notification_h noti,
1163                 void (*result_cb)(int priv_id, int result, void *data), void *user_data, uid_t uid)
1164 {
1165         if (noti == NULL)
1166                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1167
1168         noti->uid = uid;
1169         /* Update insert time ? */
1170         noti->insert_time = time(NULL);
1171
1172         return notification_ipc_request_update_async(noti, result_cb, user_data);
1173 }
1174
1175 EXPORT_API int notification_update_async(notification_h noti,
1176                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1177 {
1178         return notification_update_async_for_uid(noti, result_cb, user_data, getuid());
1179 }
1180
1181 EXPORT_API int notification_register_detailed_changed_cb_for_uid(
1182                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1183                 void *user_data, uid_t uid)
1184 {
1185         GList *noti_cb_list = NULL;
1186         notification_cb_info_s *noti_cb_info_new = NULL;
1187
1188         if (detailed_changed_cb == NULL)
1189                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1190
1191         if (_noti_cb_hash == NULL)
1192                 _noti_cb_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
1193
1194         noti_cb_info_new = (notification_cb_info_s *)malloc(sizeof(notification_cb_info_s));
1195         if (noti_cb_info_new == NULL) {
1196                 /* LCOV_EXCL_START */
1197                 ERR("Failed to alloc memory");
1198                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1199                 /* LCOV_EXCL_STOP */
1200         }
1201
1202         noti_cb_info_new->cb_type = NOTIFICATION_CB_DETAILED;
1203         noti_cb_info_new->changed_cb = NULL;
1204         noti_cb_info_new->detailed_changed_cb = detailed_changed_cb;
1205         noti_cb_info_new->data = user_data;
1206
1207         noti_cb_list = g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
1208
1209         if (noti_cb_list == NULL) {
1210                 noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
1211                 g_hash_table_insert(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
1212         } else {
1213                 noti_cb_list = g_list_append(noti_cb_list, noti_cb_info_new);
1214         }
1215
1216         if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE) {
1217                 notification_unregister_detailed_changed_cb_for_uid(detailed_changed_cb, user_data, uid);
1218                 return NOTIFICATION_ERROR_IO_ERROR;
1219         }
1220
1221         return NOTIFICATION_ERROR_NONE;
1222 }
1223
1224 EXPORT_API int notification_register_detailed_changed_cb(
1225                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1226                 void *user_data)
1227 {
1228         return notification_register_detailed_changed_cb_for_uid(detailed_changed_cb, user_data, getuid());
1229 }
1230
1231 static gint _noti_detailed_changed_compare(gconstpointer a, gconstpointer b)
1232 {
1233         const struct _notification_cb_info *info = NULL;
1234
1235         if (!a)
1236                 return -1;
1237         info = (notification_cb_info_s *)a;
1238
1239         if (info->detailed_changed_cb == b)
1240                 return 0;
1241
1242         return 1;
1243 }
1244
1245 EXPORT_API int notification_unregister_detailed_changed_cb_for_uid(
1246                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1247                 void *user_data, uid_t uid)
1248 {
1249         notification_cb_info_s *noti_cb_info;
1250         GList *noti_cb_list;
1251         GList *delete_cb_list;
1252
1253         if (detailed_changed_cb == NULL)
1254                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1255
1256         if (_noti_cb_hash == NULL)
1257                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1258
1259         noti_cb_list = (GList *)g_hash_table_lookup(_noti_cb_hash, GUINT_TO_POINTER(uid));
1260
1261         if (noti_cb_list == NULL)
1262                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1263
1264         noti_cb_list = g_list_first(noti_cb_list);
1265         delete_cb_list = g_list_find_custom(noti_cb_list, (gconstpointer)detailed_changed_cb,
1266                                             (GCompareFunc)_noti_detailed_changed_compare);
1267
1268         if (delete_cb_list) {
1269                 noti_cb_info = (notification_cb_info_s *)g_list_nth_data(delete_cb_list, 0);
1270                 noti_cb_list = g_list_delete_link(noti_cb_list, delete_cb_list);
1271                 __free_changed_cb_info(noti_cb_info);
1272                 if (noti_cb_list == NULL) {
1273                         g_hash_table_steal(_noti_cb_hash, GUINT_TO_POINTER(uid));
1274                 } else {
1275                         noti_cb_list = g_list_first(noti_cb_list);
1276                         g_hash_table_replace(_noti_cb_hash, GUINT_TO_POINTER(uid), noti_cb_list);
1277                 }
1278
1279         } else {
1280                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1281         }
1282
1283         if (g_hash_table_size(_noti_cb_hash) == 0)
1284                 notification_ipc_monitor_fini();
1285
1286         return NOTIFICATION_ERROR_NONE;
1287
1288 }
1289
1290 EXPORT_API int notification_unregister_detailed_changed_cb(
1291                 void (*detailed_changed_cb)(void *data, notification_type_e type, notification_op *op_list, int num_op),
1292                 void *user_data)
1293 {
1294         return notification_unregister_detailed_changed_cb_for_uid(detailed_changed_cb, user_data, getuid());
1295 }
1296
1297 /* LCOV_EXCL_START */
1298 EXPORT_API int notification_is_service_ready(void)
1299 {
1300         return notification_ipc_is_master_ready();
1301 }
1302 /* LCOV_EXCL_STOP */
1303
1304 EXPORT_API int notification_set_uid(notification_h noti,
1305                 uid_t uid)
1306 {
1307         if (noti == NULL)
1308                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1309
1310         noti->uid = uid;
1311         return NOTIFICATION_ERROR_NONE;
1312 }
1313
1314 EXPORT_API int notification_get_uid(notification_h noti,
1315                 uid_t *uid)
1316 {
1317         if (noti == NULL || uid == NULL)
1318                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1319
1320         *uid = noti->uid;
1321         return NOTIFICATION_ERROR_NONE;
1322 }
1323
1324 static GList *__copy_private_file(notification_h noti)
1325 {
1326         bundle *dst_b;
1327         bundle *src_b;
1328         char buf_key[32];
1329         char *src_path;
1330         char *dst_path;
1331         int i;
1332         GList *file_list = NULL;
1333         int ret;
1334
1335         if (noti->b_priv_image_path && noti->b_image_path) {
1336                 dst_b = noti->b_priv_image_path;
1337                 src_b = noti->b_image_path;
1338                 for (i = NOTIFICATION_IMAGE_TYPE_ICON; i <= NOTIFICATION_IMAGE_TYPE_MAX; i++) {
1339                         src_path = NULL;
1340                         dst_path = NULL;
1341
1342                         snprintf(buf_key, sizeof(buf_key), "%d", i);
1343
1344                         bundle_get_str(dst_b, buf_key, &dst_path);
1345                         if (dst_path == NULL)
1346                                 continue;
1347
1348                         bundle_get_str(src_b, buf_key, &src_path);
1349                         if (src_path == NULL)
1350                                 continue;
1351
1352                         ret = notification_copy_private_file(src_path, dst_path);
1353                         if (ret == NOTIFICATION_ERROR_NONE)
1354                                 file_list = g_list_append(file_list, strdup(dst_path));
1355                 }
1356         }
1357         if (noti->sound_path && noti->priv_sound_path) {
1358                 ret = notification_copy_private_file(noti->sound_path,
1359                                                      noti->priv_sound_path);
1360                 if (ret == NOTIFICATION_ERROR_NONE)
1361                         file_list = g_list_append(file_list,
1362                                                   strdup(noti->priv_sound_path));
1363         }
1364
1365         if (noti->vibration_path && noti->priv_vibration_path) {
1366                 ret = notification_copy_private_file(noti->vibration_path,
1367                                                      noti->priv_vibration_path);
1368                 if (ret == NOTIFICATION_ERROR_NONE)
1369                         file_list = g_list_append(file_list,
1370                                                   strdup(noti->priv_vibration_path));
1371         }
1372
1373         return file_list;
1374 }
1375
1376 /* LCOV_EXCL_START */
1377 static void __remove_private_file(gpointer data, gpointer user_data)
1378 {
1379         GFile *src = NULL;
1380         char *path = (char *)data;
1381
1382         src = g_file_new_for_path(path);
1383         if (src) {
1384                 g_file_delete(src, NULL, NULL);
1385                 g_object_unref(src);
1386         }
1387 }
1388 /* LCOV_EXCL_STOP */
1389
1390 EXPORT_API int notification_post_for_uid(notification_h noti, uid_t uid)
1391 {
1392         int ret = 0;
1393         int id = 0;
1394         GList *file_list;
1395
1396         if (noti == NULL)
1397                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1398
1399         if (noti->type <= NOTIFICATION_TYPE_NONE
1400                         || noti->type > NOTIFICATION_TYPE_MAX)
1401                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1402
1403         /* Save insert time */
1404         noti->insert_time = time(NULL);
1405         noti->uid = uid;
1406
1407         file_list = __copy_private_file(noti);
1408         ret = notification_ipc_request_insert(noti, &id);
1409         if (ret == NOTIFICATION_ERROR_NONE) {
1410                 noti->priv_id = id;
1411                 INFO("Posted notification id[%d]", id);
1412         } else {
1413                 g_list_foreach(file_list, __remove_private_file, NULL);
1414         }
1415
1416         if (file_list)
1417                 g_list_free_full(file_list, free);
1418
1419         return ret;
1420 }
1421
1422 EXPORT_API int notification_update_for_uid(notification_h noti, uid_t uid)
1423 {
1424         if (noti == NULL) {
1425                 notification_ipc_request_refresh(uid);
1426                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1427         }
1428
1429         noti->uid = uid;
1430         /* Update insert time ? */
1431         noti->insert_time = time(NULL);
1432
1433         return notification_ipc_request_update(noti);
1434 }
1435
1436 EXPORT_API int notification_delete_for_uid(notification_h noti, uid_t uid)
1437 {
1438         if (noti == NULL)
1439                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1440
1441         return notification_ipc_request_delete_single(NOTIFICATION_TYPE_NONE,
1442                                 noti->caller_app_id, noti->priv_id, uid);
1443 }
1444
1445 EXPORT_API int notification_delete_all_for_uid(notification_type_e type, uid_t uid)
1446 {
1447         int ret = 0;
1448         char *caller_app_id = NULL;
1449
1450         if (type <= NOTIFICATION_TYPE_NONE || type > NOTIFICATION_TYPE_MAX)
1451                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1452
1453         caller_app_id = notification_get_app_id_by_pid(getpid());
1454
1455         ret = notification_ipc_request_delete_multiple(type, caller_app_id, uid);
1456
1457         if (caller_app_id)
1458                 free(caller_app_id);
1459
1460         return ret;
1461 }
1462
1463 EXPORT_API notification_h notification_load_by_tag_for_uid(const char *tag, uid_t uid)
1464 {
1465         int ret;
1466         notification_h noti;
1467         char *caller_app_id;
1468
1469         if (tag == NULL) {
1470                 ERR("Invalid tag");
1471                 set_last_result(NOTIFICATION_ERROR_INVALID_PARAMETER);
1472                 return NULL;
1473         }
1474
1475         caller_app_id = notification_get_app_id_by_pid(getpid());
1476         if (!caller_app_id) {
1477                 /* LCOV_EXCL_START */
1478                 ERR("Failed to get a package name");
1479                 set_last_result(NOTIFICATION_ERROR_OUT_OF_MEMORY);
1480                 return NULL;
1481                 /* LCOV_EXCL_STOP */
1482         }
1483
1484         noti = (notification_h)calloc(1, sizeof(struct _notification));
1485         if (noti == NULL) {
1486                 /* LCOV_EXCL_START */
1487                 ERR("Failed to alloc a new notification");
1488                 set_last_result(NOTIFICATION_ERROR_OUT_OF_MEMORY);
1489                 free(caller_app_id);
1490
1491                 return NULL;
1492                 /* LCOV_EXCL_STOP */
1493         }
1494
1495         ret = notification_ipc_request_load_noti_by_tag(noti, caller_app_id, (char *)tag, uid);
1496         free(caller_app_id);
1497
1498         set_last_result(ret);
1499         if (ret != NOTIFICATION_ERROR_NONE) {
1500                 notification_free(noti);
1501                 return NULL;
1502         }
1503
1504         return noti;
1505 }
1506
1507 EXPORT_API notification_h notification_create_from_package_template(const char *app_id, const char *template_name)
1508 {
1509         int ret;
1510         notification_h noti;
1511
1512         if (app_id == NULL || template_name == NULL) {
1513                 ERR("Invalid parameter");
1514                 set_last_result(NOTIFICATION_ERROR_INVALID_PARAMETER);
1515                 return NULL;
1516         }
1517
1518         noti = (notification_h)calloc(1, sizeof(struct _notification));
1519         if (noti == NULL) {
1520                 /* LCOV_EXCL_START */
1521                 ERR("Failed to alloc memory");
1522                 set_last_result(NOTIFICATION_ERROR_OUT_OF_MEMORY);
1523                 return NULL;
1524                 /* LCOV_EXCL_STOP */
1525         }
1526
1527         ret = notification_ipc_request_create_from_package_template(noti, app_id, template_name);
1528         set_last_result(ret);
1529         if (ret != NOTIFICATION_ERROR_NONE) {
1530                 notification_free(noti);
1531                 return NULL;
1532         }
1533
1534         return noti;
1535 }
1536
1537 EXPORT_API int notification_set_default_button(notification_h noti, notification_button_index_e index)
1538 {
1539         if (noti == NULL)
1540                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1541
1542         if (index < 0 || index > NOTIFICATION_BUTTON_6)
1543                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1544
1545         noti->default_button_index = index;
1546
1547         return NOTIFICATION_ERROR_NONE;
1548 }
1549
1550 EXPORT_API int notification_get_default_button(notification_h noti, notification_button_index_e *index)
1551 {
1552         if (noti == NULL || index == NULL)
1553                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1554
1555         *index = noti->default_button_index;
1556
1557         return NOTIFICATION_ERROR_NONE;
1558 }
1559
1560 EXPORT_API int notification_get_ongoing_value_type(notification_h noti, notification_ongoing_value_type_e *type)
1561 {
1562         if (noti == NULL || type == NULL)
1563                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1564
1565         *type = noti->ongoing_value_type;
1566
1567         return NOTIFICATION_ERROR_NONE;
1568 }
1569
1570 EXPORT_API int notification_set_ongoing_value_type(notification_h noti, notification_ongoing_value_type_e type)
1571 {
1572         if (noti == NULL)
1573                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1574
1575         if (type < NOTIFICATION_ONGOING_VALUE_TYPE_PERCENT || type > NOTIFICATION_ONGOING_VALUE_TYPE_TIME)
1576                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1577
1578         noti->ongoing_value_type = type;
1579
1580         return NOTIFICATION_ERROR_NONE;
1581 }
1582
1583 EXPORT_API int notification_get_ongoing_time(notification_h noti, int *current, int *duration)
1584 {
1585         if (noti == NULL || current == NULL || duration == NULL)
1586                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1587
1588         *current = noti->ongoing_current;
1589         *duration = noti->ongoing_duration;
1590
1591         return NOTIFICATION_ERROR_NONE;
1592 }
1593
1594 EXPORT_API int notification_set_ongoing_time(notification_h noti, int current, int duration)
1595 {
1596         if (noti == NULL)
1597                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1598
1599         if (current < 0 || duration < 0 || current > duration)
1600                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1601
1602         noti->ongoing_current = current;
1603         noti->ongoing_duration = duration;
1604
1605         return NOTIFICATION_ERROR_NONE;
1606 }
1607
1608 EXPORT_API int notification_get_hide_timeout(notification_h noti, int *timeout)
1609 {
1610         if (noti == NULL || timeout == NULL)
1611                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1612
1613         *timeout = noti->hide_timeout;
1614
1615         return NOTIFICATION_ERROR_NONE;
1616 }
1617
1618 EXPORT_API int notification_set_hide_timeout(notification_h noti, int timeout)
1619 {
1620         if (noti == NULL || timeout < 0)
1621                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1622
1623         noti->hide_timeout = timeout;
1624
1625         return NOTIFICATION_ERROR_NONE;
1626 }
1627
1628 EXPORT_API int notification_get_delete_timeout(notification_h noti, int *timeout)
1629 {
1630         if (noti == NULL || timeout == NULL)
1631                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1632
1633         *timeout = noti->delete_timeout;
1634
1635         return NOTIFICATION_ERROR_NONE;
1636 }
1637
1638 EXPORT_API int notification_set_delete_timeout(notification_h noti, int timeout)
1639 {
1640         if (noti == NULL || timeout < 0)
1641                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1642
1643         noti->delete_timeout = timeout;
1644
1645         return NOTIFICATION_ERROR_NONE;
1646 }
1647
1648 EXPORT_API int notification_get_text_input_max_length(notification_h noti, int *text_input_max_length)
1649 {
1650         if (noti == NULL || text_input_max_length == NULL)
1651                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1652
1653         *text_input_max_length = noti->text_input_max_length;
1654
1655         return NOTIFICATION_ERROR_NONE;
1656 }
1657
1658 EXPORT_API int notification_post_with_event_cb_for_uid(notification_h noti, event_handler_cb cb,
1659                                                         void *userdata, uid_t uid)
1660 {
1661         int ret;
1662         int priv_id;
1663         notification_event_cb_info_s *info = NULL;
1664         GList *find_list;
1665
1666         if (noti == NULL || cb == NULL)
1667                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1668
1669         if (noti->type <= NOTIFICATION_TYPE_NONE || noti->type > NOTIFICATION_TYPE_MAX)
1670                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1671
1672         noti->insert_time = time(NULL);
1673         noti->event_flag = true;
1674         noti->uid = uid;
1675
1676         ret = notification_ipc_request_insert(noti, &priv_id);
1677         if (ret != NOTIFICATION_ERROR_NONE)
1678                 return ret;
1679
1680         noti->priv_id = priv_id;
1681
1682         __noti_event_cb_list = g_list_first(__noti_event_cb_list);
1683         find_list = g_list_find_custom(__noti_event_cb_list, GINT_TO_POINTER(priv_id),
1684                                        (GCompareFunc)__priv_id_compare);
1685
1686         if (find_list) {
1687                 info = g_list_nth_data(find_list, 0);
1688                 info->cb = cb;
1689                 info->userdata = userdata;
1690         } else {
1691                 info = (notification_event_cb_info_s *)malloc(sizeof(notification_event_cb_info_s));
1692                 if (info == NULL) {
1693                         /* LCOV_EXCL_START */
1694                         ERR("Failed to alloc memory");
1695                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1696                         /* LCOV_EXCL_STOP */
1697                 }
1698                 info->priv_id = priv_id;
1699                 info->cb = cb;
1700                 info->userdata = userdata;
1701                 __noti_event_cb_list = g_list_append(__noti_event_cb_list, info);
1702         }
1703
1704         return ret;
1705 }
1706
1707 EXPORT_API int notification_post_with_event_cb(notification_h noti, event_handler_cb cb, void *userdata)
1708 {
1709         return notification_post_with_event_cb_for_uid(noti, cb, userdata, getuid());
1710 }
1711
1712 EXPORT_API int notification_send_event(notification_h noti, int event_type)
1713 {
1714         int ret;
1715         bool event_flag;
1716
1717         if (noti == NULL)
1718                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1719
1720         if (!((event_type >= NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1
1721                 && event_type <= NOTIFICATION_EVENT_TYPE_MAX) ||
1722                 (event_type >= NOTIFICATION_EVENT_TYPE_HIDDEN_BY_USER
1723                 && event_type <= NOTIFICATION_EVENT_TYPE_HIDDEN_BY_EXTERNAL) ||
1724                 (event_type >= NOTIFICATION_EVENT_TYPE_PRESSED
1725                 && event_type <= NOTIFICATION_EVENT_TYPE_DELETED)))
1726                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1727
1728         ret = notification_get_event_flag(noti, &event_flag);
1729         if (ret != NOTIFICATION_ERROR_NONE || event_flag == false)
1730                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1731
1732         ret = notification_ipc_send_event(noti, event_type, -1);
1733
1734         return ret;
1735 }
1736
1737 EXPORT_API int notification_send_event_by_priv_id(int priv_id, int event_type)
1738 {
1739         int ret;
1740
1741         if (priv_id <= 0)
1742                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1743
1744         if (!((event_type >= NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1
1745                 && event_type <= NOTIFICATION_EVENT_TYPE_MAX) ||
1746                 (event_type >= NOTIFICATION_EVENT_TYPE_HIDDEN_BY_USER
1747                 && event_type <= NOTIFICATION_EVENT_TYPE_HIDDEN_BY_EXTERNAL) ||
1748                 (event_type >= NOTIFICATION_EVENT_TYPE_PRESSED
1749                 && event_type <= NOTIFICATION_EVENT_TYPE_DELETED)))
1750                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1751
1752         ret = notification_ipc_send_event(NULL, event_type, priv_id);
1753         return ret;
1754 }
1755
1756 EXPORT_API int notification_get_event_flag(notification_h noti, bool *flag)
1757 {
1758         if (noti == NULL || flag == NULL)
1759                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1760
1761         *flag = noti->event_flag;
1762
1763         return NOTIFICATION_ERROR_NONE;
1764 }
1765
1766 EXPORT_API int notification_check_event_receiver_available(notification_h noti, bool *available)
1767 {
1768         int ret;
1769         int priv_id;
1770
1771         if (noti == NULL || available == NULL)
1772                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1773
1774         ret = notification_get_id(noti, NULL, &priv_id);
1775         if (ret != NOTIFICATION_ERROR_NONE) {
1776                 ERR("Failed to get priv id");
1777                 return ret;
1778         }
1779
1780         ret = notification_ipc_check_event_receiver(priv_id, available);
1781
1782         return ret;
1783 }
1784
1785 static bundle *_create_bundle_from_bundle_raw(bundle_raw *string)
1786 {
1787         if (string == NULL || string[0] == '\0')
1788                 return NULL;
1789
1790         return bundle_decode(string, strlen((char *)string));
1791 }
1792
1793 EXPORT_API int notification_set_extention_data(notification_h noti, const char *key, bundle *value)
1794 {
1795         return notification_set_extension_data(noti, key, value);
1796 }
1797
1798 EXPORT_API int notification_set_extension_data(notification_h noti, const char *key, bundle *value)
1799 {
1800         int ret;
1801         int len = 0;
1802         char *del = NULL;
1803         bundle_raw *raw = NULL;
1804
1805         if (noti == NULL || key == NULL)
1806                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1807
1808         if (noti->args == NULL)
1809                 noti->args = bundle_create();
1810
1811         if (value == NULL) {
1812                 ret = bundle_del(noti->args, key);
1813                 if (ret == BUNDLE_ERROR_NONE)
1814                         return NOTIFICATION_ERROR_NONE;
1815                 else
1816                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
1817         }
1818
1819         bundle_get_str(noti->args, key, &del);
1820         if (del != NULL) {
1821                 bundle_del(noti->args, key);
1822                 del = NULL;
1823         }
1824
1825         bundle_encode(value, &raw, &len);
1826         bundle_add_str(noti->args, key, (const char *)raw);
1827         bundle_free_encoded_rawdata(&raw);
1828
1829         return NOTIFICATION_ERROR_NONE;
1830 }
1831
1832 EXPORT_API int notification_get_extention_data(notification_h noti, const char *key, bundle **value)
1833 {
1834         return notification_get_extension_data(noti, key, value);
1835 }
1836
1837 EXPORT_API int notification_get_extension_data(notification_h noti, const char *key, bundle **value)
1838 {
1839         char *ret_str;
1840         bundle *args;
1841
1842         if (noti == NULL || key == NULL || value == NULL)
1843                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1844
1845         if (noti->args == NULL)
1846                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1847
1848         args = noti->args;
1849
1850         bundle_get_str(args, key, &ret_str);
1851         if (ret_str == NULL)
1852                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1853
1854         *value = _create_bundle_from_bundle_raw((bundle_raw *)ret_str);
1855         if (*value == NULL)
1856                 return NOTIFICATION_ERROR_IO_ERROR;
1857
1858         return NOTIFICATION_ERROR_NONE;
1859 }
1860
1861 #define KEY_LEN 40
1862 #define EXTENSION_EVENT_KEY "_NOTIFICATION_EXTENSION_EVENT_"
1863 EXPORT_API int notification_set_extension_event_handler(notification_h noti,
1864                                         notification_event_type_extension_e event,
1865                                         app_control_h event_handler)
1866 {
1867         int err;
1868         int ret = NOTIFICATION_ERROR_NONE;
1869         int len;
1870         bundle *app_control_bundle = NULL;
1871         bundle_raw *b_raw = NULL;
1872         char key[KEY_LEN];
1873         char *del = NULL;
1874
1875         if (noti == NULL || event_handler == NULL) {
1876                 ERR("Invalid parameter");
1877                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1878         }
1879
1880         if (event < NOTIFICATION_EVENT_TYPE_HIDDEN_BY_USER ||
1881             event > NOTIFICATION_EVENT_TYPE_HIDDEN_BY_EXTERNAL) {
1882                 ERR("Invalid event [%d]", event);
1883                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1884         }
1885
1886         if (noti->args == NULL)
1887                 noti->args = bundle_create();
1888
1889         snprintf(key, sizeof(key), "%s%d", EXTENSION_EVENT_KEY, event);
1890         bundle_get_str(noti->args, key, &del);
1891         if (del != NULL) {
1892                 bundle_del(noti->args, key);
1893                 del = NULL;
1894         }
1895
1896         err = app_control_export_as_bundle(event_handler, &app_control_bundle);
1897         if (err != APP_CONTROL_ERROR_NONE) {
1898                 /* LCOV_EXCL_START */
1899                 ERR("Failed to export app_control to bundle [%d]", err);
1900                 ret = NOTIFICATION_ERROR_IO_ERROR;
1901                 goto out;
1902                 /* LCOV_EXCL_STOP */
1903         }
1904
1905         err = bundle_encode(app_control_bundle, &b_raw, &len);
1906         if (err != BUNDLE_ERROR_NONE) {
1907                 /* LCOV_EXCL_START */
1908                 ERR("Failed to encode bundle [%d]", err);
1909                 ret = NOTIFICATION_ERROR_IO_ERROR;
1910                 goto out;
1911                 /* LCOV_EXCL_STOP */
1912         }
1913
1914         err = bundle_add_str(noti->args, key, (const char *)b_raw);
1915         if (err != BUNDLE_ERROR_NONE) {
1916                 /* LCOV_EXCL_START */
1917                 ERR("Failed to add str to bundle [%d]", err);
1918                 ret = NOTIFICATION_ERROR_IO_ERROR;
1919                 goto out;
1920                 /* LCOV_EXCL_STOP */
1921         }
1922
1923 out:
1924         if (b_raw)
1925                 bundle_free_encoded_rawdata(&b_raw);
1926         if (app_control_bundle)
1927                 bundle_free(app_control_bundle);
1928
1929         return ret;
1930 }
1931
1932 EXPORT_API int notification_get_extension_event_handler(notification_h noti,
1933                                         notification_event_type_extension_e event,
1934                                         app_control_h *event_handler)
1935 {
1936         int err;
1937         int ret = NOTIFICATION_ERROR_NONE;
1938         char *ret_str = NULL;
1939         char key[KEY_LEN];
1940         bundle *app_control_bundle = NULL;
1941         app_control_h ret_app_control = NULL;
1942
1943         if (noti == NULL || event_handler == NULL) {
1944                 ERR("Invalid parameter");
1945                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1946         }
1947
1948         if (event < NOTIFICATION_EVENT_TYPE_HIDDEN_BY_USER ||
1949             event > NOTIFICATION_EVENT_TYPE_HIDDEN_BY_EXTERNAL) {
1950                 ERR("Invalid event [%d]", event);
1951                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1952         }
1953
1954         snprintf(key, sizeof(key), "%s%d", EXTENSION_EVENT_KEY, event);
1955
1956         bundle_get_str(noti->args, key, &ret_str);
1957         if (ret_str == NULL) {
1958                 ERR("No handler, Invalid event[%d]", event);
1959                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1960         }
1961
1962         app_control_bundle = _create_bundle_from_bundle_raw((bundle_raw *)ret_str);
1963         if (app_control_bundle == NULL) {
1964                 /* LCOV_EXCL_START */
1965                 ERR("Failed to create bundle");
1966                 return NOTIFICATION_ERROR_IO_ERROR;
1967                 /* LCOV_EXCL_STOP */
1968         }
1969
1970         err = app_control_create(&ret_app_control);
1971         if (err != APP_CONTROL_ERROR_NONE) {
1972                 /* LCOV_EXCL_START */
1973                 ERR("Failed to create app control [%d]", err);
1974                 ret = NOTIFICATION_ERROR_IO_ERROR;
1975                 goto out;
1976                 /* LCOV_EXCL_STOP */
1977         }
1978
1979         err = app_control_import_from_bundle(ret_app_control, app_control_bundle);
1980         if (err != APP_CONTROL_ERROR_NONE) {
1981                 /* LCOV_EXCL_START */
1982                 ERR("Failed to import app control from bundle [%d]", err);
1983                 app_control_destroy(ret_app_control);
1984                 ret = NOTIFICATION_ERROR_IO_ERROR;
1985                 goto out;
1986                 /* LCOV_EXCL_STOP */
1987         }
1988
1989         *event_handler = ret_app_control;
1990
1991 out:
1992         if (app_control_bundle)
1993                 bundle_free(app_control_bundle);
1994
1995         return ret;
1996 }
1997
1998 EXPORT_API int notification_get_all_count_for_uid(notification_type_e type, int *count, uid_t uid)
1999 {
2000         int ret;
2001
2002         if (count == NULL) {
2003                 ERR("Invalid parameter - count is null");
2004                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2005         }
2006
2007         if (type < NOTIFICATION_TYPE_NONE || type > NOTIFICATION_TYPE_MAX) {
2008                 ERR("Invalid parameter - wrong type");
2009                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2010         }
2011
2012         ret = notification_ipc_request_get_all_count(type, count, uid);
2013         if (ret != NOTIFICATION_ERROR_NONE) {
2014                 ERR("Failed to get count [%d]", ret);
2015                 return ret;
2016         }
2017
2018         return ret;
2019 }
2020
2021 EXPORT_API int notification_get_all_count(notification_type_e type, int *count)
2022 {
2023         return notification_get_all_count_for_uid(type, count, getuid());
2024 }
2025
2026 EXPORT_API int notification_set_app_label(notification_h noti, char *label)
2027 {
2028         if (noti == NULL || label == NULL)
2029                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2030
2031         if (noti->app_label)
2032                 free(noti->app_label);
2033
2034         noti->app_label = strdup(label);
2035
2036         return NOTIFICATION_ERROR_NONE;
2037 }
2038
2039 EXPORT_API int notification_get_app_label(notification_h noti, char **label)
2040 {
2041         if (noti == NULL || label == NULL)
2042                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2043
2044         if (noti->app_label)
2045                 *label = noti->app_label;
2046
2047         return NOTIFICATION_ERROR_NONE;
2048 }
2049
2050 static void __set_caller_info(bundle *b, const char *appid, uid_t uid)
2051 {
2052         pkgmgrinfo_appinfo_h handle;
2053         char buf[12];
2054         char *pkgid = NULL;
2055         int r;
2056
2057         snprintf(buf, sizeof(buf), "%u", uid);
2058         bundle_del(b, AUL_K_ORG_CALLER_UID);
2059         bundle_add(b, AUL_K_ORG_CALLER_UID, buf);
2060
2061         bundle_del(b, AUL_K_ORG_CALLER_APPID);
2062         bundle_add(b, AUL_K_ORG_CALLER_APPID, appid);
2063
2064         r = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
2065         if (r != PMINFO_R_OK)
2066                 return;
2067
2068         pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2069         if (pkgid) {
2070                 bundle_del(b, AUL_K_ORG_CALLER_PKGID);
2071                 bundle_add(b, AUL_K_ORG_CALLER_PKGID, pkgid);
2072         }
2073         pkgmgrinfo_appinfo_destroy_appinfo(handle);
2074 }
2075
2076 static void __set_indirect_request(bundle *b)
2077 {
2078         bundle_del(b, AUL_K_REQUEST_TYPE);
2079         bundle_add(b, AUL_K_REQUEST_TYPE, "indirect-request");
2080 }
2081
2082 EXPORT_API int notification_set_indirect_request(notification_h noti,
2083                 pid_t pid, uid_t uid)
2084 {
2085         char appid[256] = { 0, };
2086         int r;
2087         int i;
2088
2089         if (noti == NULL || pid <= 1 || uid < REGULAR_UID_MIN)
2090                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2091
2092         r = aul_app_get_appid_bypid(pid, appid, sizeof(appid));
2093         if (r != AUL_R_OK)
2094                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2095
2096         if (noti->b_service_responding) {
2097                 __set_caller_info(noti->b_service_responding, appid, uid);
2098                 __set_indirect_request(noti->b_service_responding);
2099         }
2100
2101         if (noti->b_service_single_launch) {
2102                 __set_caller_info(noti->b_service_single_launch, appid, uid);
2103                 __set_indirect_request(noti->b_service_single_launch);
2104         }
2105
2106         if (noti->b_service_multi_launch) {
2107                 __set_caller_info(noti->b_service_multi_launch, appid, uid);
2108                 __set_indirect_request(noti->b_service_multi_launch);
2109         }
2110
2111         for (i = 0; i <= NOTIFICATION_EVENT_TYPE_MAX; i++) {
2112                 if (noti->b_event_handler[i]) {
2113                         __set_caller_info(noti->b_event_handler[i], appid, uid);
2114                         __set_indirect_request(noti->b_event_handler[i]);
2115                 }
2116         }
2117
2118         return NOTIFICATION_ERROR_NONE;
2119 }
2120
2121
2122 int notification_delete_by_display_applist_for_uid(int display_applist, uid_t uid)
2123 {
2124         if (display_applist < NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)
2125                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
2126
2127         return notification_ipc_request_delete_by_display_applist(display_applist, uid);
2128 }
2129
2130 EXPORT_API int notification_delete_by_display_applist(int display_applist)
2131 {
2132         return notification_delete_by_display_applist_for_uid(display_applist, getuid());
2133 }