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