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