Merge "Update preference api source from tizen_2.3" into tizen
[platform/core/api/application.git] / src / ui_notification.c
1 /*
2  * Copyright (c) 2011 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
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdarg.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25
26 #include <dlog.h>
27 #include <notification.h>
28
29 #include <app.h>
30 #include <app_service_private.h>
31
32 #ifdef LOG_TAG
33 #undef LOG_TAG
34 #endif
35
36 #define LOG_TAG "CAPI_APPFW_APPLICATION_UI_NOTIFICATION"
37
38 struct ui_notification_s {
39         notification_h raw_handle;
40         bool ongoing;
41         bool posted;
42         bool removed;
43         char *icon;
44         struct tm *time;
45         char *title;
46         char *content;
47         service_h service;
48         char *sound;
49         bool vibration;
50 };
51
52 static int ui_notification_error_handler(int error, const char *func, const char *on_error)
53 {
54         int retcode;
55         char *error_msg;
56
57         switch (error)
58         {
59         case NOTIFICATION_ERROR_NONE:
60                 retcode = UI_NOTIFICATION_ERROR_NONE;
61                 break;
62
63         case NOTIFICATION_ERROR_INVALID_DATA:
64                 retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
65                 error_msg = "INVALID_PARAMETER";
66                 break;
67
68         case NOTIFICATION_ERROR_NO_MEMORY:
69                 retcode = UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
70                 error_msg = "OUT_OF_MEMORY";
71                 break;
72
73         case NOTIFICATION_ERROR_FROM_DB:
74                 retcode = UI_NOTIFICATION_ERROR_DB_FAILED;
75                 error_msg = "DB_FAILED";
76                 break;
77
78         case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
79         case NOTIFICATION_ERROR_NOT_EXIST_ID:
80                 retcode = UI_NOTIFICATION_ERROR_INVALID_STATE;
81                 error_msg = "INVALID_STATE";
82                 break;
83
84         default:
85                 retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
86                 error_msg = "INVALID_PARAMETER";
87         }
88
89         if (retcode != UI_NOTIFICATION_ERROR_NONE)
90         {
91                 LOGE("[%s] %s(0x%08x) : %s", func, error_msg, retcode, on_error);
92         }
93
94         return retcode;
95 }
96
97
98 int ui_notification_create(bool ongoing, ui_notification_h *notification)
99 {
100         ui_notification_h notification_out;
101
102         if (notification == NULL)
103         {
104                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
105                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
106         }
107
108         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
109
110         if (notification_out == NULL)
111         {
112                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
113                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
114         }
115
116         notification_out->raw_handle = NULL;
117         notification_out->ongoing = ongoing;
118         notification_out->posted = false;
119         notification_out->removed = false;
120         notification_out->icon = NULL;
121         notification_out->time = NULL;
122         notification_out->title = NULL;
123         notification_out->content = NULL;
124         notification_out->service = NULL;
125         notification_out->sound = NULL;
126         notification_out->vibration = false;
127
128         *notification = notification_out;
129
130         return UI_NOTIFICATION_ERROR_NONE;
131 }
132
133 static int ui_notification_construct(bool ongoing, notification_h raw_handle, ui_notification_h *notification)
134 {
135         int retcode;
136         ui_notification_h notification_out;
137         char *icon;
138         time_t time;
139         char *title;
140         char *content;
141         bundle *service_data;
142         const char *sound = NULL;
143         notification_sound_type_e sound_type;
144         notification_vibration_type_e vib_type;
145
146         if (notification == NULL)
147         {
148                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
149                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
150         }
151
152         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
153
154         if (notification_out == NULL)
155         {
156                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
157                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
158         }
159
160         retcode = ui_notification_error_handler(notification_clone(raw_handle, &(notification_out->raw_handle)),\
161                                  __FUNCTION__, "failed to clone the notification handle");
162
163         if (retcode != NOTIFICATION_ERROR_NONE)
164         {
165                 free(notification_out);
166                 return retcode;
167         }
168
169         notification_out->ongoing = ongoing;
170
171         notification_out->posted = true;
172
173         notification_out->removed = false;
174
175         if (!notification_get_image(raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, &icon) && icon)
176         {
177                 notification_out->icon = strdup(icon);
178         }
179
180         if (!notification_get_time(raw_handle, &time))
181         {
182                 notification_out->time = malloc(sizeof(struct tm));
183
184                 if (notification_out->time == NULL)
185                 {
186                         ui_notification_destroy(notification_out);
187                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
188                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
189                 }
190
191                 localtime_r(&time, notification_out->time);
192         }
193
194         if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, &title) && title)
195         {
196                 notification_out->title = strdup(title);
197         }
198
199         if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &content) && content)
200         {
201                 notification_out->content = strdup(content);
202         }
203
204         if (!notification_get_sound(raw_handle, &sound_type, &sound) && sound)
205         {
206                 notification_out->sound = strdup(sound);
207         }
208
209         if (!notification_get_vibration(raw_handle, &vib_type, NULL))
210         {
211                 if (vib_type == NOTIFICATION_VIBRATION_TYPE_DEFAULT)
212                 {
213                         notification_out->vibration = true;
214                 }
215         }
216
217         if (!notification_get_execute_option(raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, &service_data))
218         {
219                 service_h service;
220
221                 if (!service_create_request(service_data, &service))
222                 {
223                         notification_out->service = service;
224                 }
225         }
226
227         *notification = notification_out;
228
229         return UI_NOTIFICATION_ERROR_NONE;
230 }
231
232 int ui_notification_destroy(ui_notification_h notification)
233 {
234         if (notification == NULL)
235         {
236                 LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
237                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
238         }
239
240         if (notification->raw_handle)
241                 notification_free(notification->raw_handle);
242
243         if (notification->icon)
244                 free(notification->icon);
245
246         if (notification->time)
247                 free(notification->time);
248
249         if (notification->title)
250                 free(notification->title);
251
252         if (notification->content)
253                 free(notification->content);
254
255         if (notification->sound)
256                 free(notification->sound);
257
258         if (notification->service)
259                 service_destroy(notification->service);
260
261         free(notification);
262
263         return UI_NOTIFICATION_ERROR_NONE;
264 }
265
266 int ui_notification_get_id(ui_notification_h notification, int *id)
267 {
268         notification_h raw_handle = NULL;
269
270         if (notification == NULL || id == NULL)
271         {
272                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
273                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
274         }
275         if (notification->raw_handle == NULL)
276         {
277                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
278                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
279         }
280
281         raw_handle = notification->raw_handle;
282         if (notification_get_id(raw_handle, NULL, id) != NOTIFICATION_ERROR_NONE) {
283                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
284                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
285         }
286
287         return UI_NOTIFICATION_ERROR_NONE;
288 }
289
290 int ui_notification_clone(ui_notification_h *clone, ui_notification_h notification)
291 {
292         ui_notification_h notification_out;
293         int retcode;
294
295         if (clone == NULL || notification == NULL)
296         {
297                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
298                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
299         }
300
301         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
302
303         if (notification_out == NULL)
304         {
305                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
306                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
307         }
308
309         if (notification->raw_handle != NULL)
310         {
311                 retcode = notification_clone(notification->raw_handle, &(notification_out->raw_handle));
312
313                 if (retcode)
314                 {
315                         free(notification_out);
316                         return ui_notification_error_handler(retcode, __FUNCTION__, "failed to clone the handle");
317                 }
318         }
319
320         notification_out->ongoing = notification->ongoing;
321
322         notification_out->posted = notification->posted;
323
324         notification_out->removed = notification->removed;
325
326         if (notification->icon)
327         {
328                 notification_out->icon = strdup(notification->icon);
329         }
330
331         if (notification->time)
332         {
333                 notification_out->time = malloc(sizeof(struct tm));
334                 if (notification_out->time != NULL)
335                 {
336                         memcpy(notification_out->time, notification->time, sizeof(struct tm));
337                 }
338         }
339
340         if (notification->title)
341         {
342                 notification_out->title = strdup(notification->title);
343         }
344
345         if (notification->content)
346         {
347                 notification_out->content = strdup(notification->content);
348         }
349
350         if (notification->sound)
351         {
352                 notification_out->sound = strdup(notification->sound);
353         }
354
355         notification_out->vibration = notification->vibration;
356
357         if (notification->service)
358         {
359                 service_clone(&(notification_out->service), notification->service);
360         }
361
362         *clone = notification_out;
363
364         return UI_NOTIFICATION_ERROR_NONE;
365 }
366
367 int ui_notification_is_ongoing(ui_notification_h notification, bool *ongoing)
368 {
369         if (notification == NULL || ongoing == NULL)
370         {
371                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
372                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
373         }
374
375         *ongoing = notification->ongoing;
376
377         return UI_NOTIFICATION_ERROR_NONE;
378 }
379
380 int ui_notification_set_icon(ui_notification_h notification, const char *path)
381 {
382         char *path_dup = NULL;
383
384         if (notification == NULL)
385         {
386                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
387                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
388         }
389
390         if (path != NULL)
391         {
392                 path_dup = strdup(path);
393
394                 if (path_dup == NULL)
395                 {
396                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
397                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
398                 }
399         }
400
401         if (notification->icon != NULL)
402         {
403                 free(notification->icon);
404         }
405
406         notification->icon = path_dup;
407
408         return UI_NOTIFICATION_ERROR_NONE;
409 }
410
411 int ui_notification_get_icon(ui_notification_h notification, char **path)
412 {
413         char *path_dup = NULL;
414
415         if (notification == NULL || path == NULL)
416         {
417                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
418                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
419         }
420
421         if (notification->icon != NULL)
422         {
423                 path_dup = strdup(notification->icon);
424
425                 if (path_dup == NULL)
426                 {
427                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
428                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
429                 }
430         }
431
432         *path = path_dup;
433
434         return UI_NOTIFICATION_ERROR_NONE;
435 }
436
437 int ui_notification_set_time(ui_notification_h notification, struct tm *time)
438 {
439         struct tm *time_dup = NULL;
440
441         if (notification == NULL)
442         {
443                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
444                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
445         }
446
447         if (time != NULL)
448         {
449                 time_dup = malloc(sizeof(struct tm));
450
451                 if (time_dup == NULL)
452                 {
453                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
454                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
455                 }
456
457                 memcpy(time_dup, time, sizeof(struct tm));
458         }
459
460         if (notification->time != NULL)
461         {
462                 free(notification->time);
463         }
464
465         notification->time = time_dup;
466
467         return UI_NOTIFICATION_ERROR_NONE;
468 }
469
470 int ui_notification_get_time(ui_notification_h notification, struct tm **time)
471 {
472         struct tm *time_dup = NULL;
473
474         if (notification == NULL || time == NULL)
475         {
476                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
477                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
478         }
479
480         if (notification->time != NULL)
481         {
482                 time_dup = malloc(sizeof(struct tm));
483
484                 if (time_dup == NULL)
485                 {
486                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
487                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
488                 }
489
490                 memcpy(time_dup, notification->time, sizeof(struct tm));
491         }
492
493         *time = time_dup;
494
495         return UI_NOTIFICATION_ERROR_NONE;
496 }
497
498 int ui_notification_set_title(ui_notification_h notification, const char *title)
499 {
500         char *title_dup = NULL;
501
502         if (notification == NULL)
503         {
504                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
505                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
506         }
507
508         if (title != NULL)
509         {
510                 title_dup = strdup(title);
511
512                 if (title_dup == NULL)
513                 {
514                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
515                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
516                 }
517         }
518
519         if (notification->title != NULL)
520         {
521                 free(notification->title);
522         }
523
524         notification->title = title_dup;
525
526         return UI_NOTIFICATION_ERROR_NONE;
527 }
528
529 int ui_notification_get_title(ui_notification_h notification, char **title)
530 {
531         char *title_dup = NULL;
532
533         if (notification == NULL || title == NULL)
534         {
535                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
536                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
537         }
538
539         if (notification->title != NULL)
540         {
541                 title_dup = strdup(notification->title);
542
543                 if (title_dup == NULL)
544                 {
545                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
546                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
547                 }
548         }
549
550         *title = title_dup;
551
552         return UI_NOTIFICATION_ERROR_NONE;
553 }
554
555
556 int ui_notification_set_content(ui_notification_h notification, const char *content)
557 {
558         char *content_dup = NULL;
559
560         if (notification == NULL)
561         {
562                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
563                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
564         }
565
566         if (content != NULL)
567         {
568                 content_dup = strdup(content);
569
570                 if (content_dup == NULL)
571                 {
572                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
573                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
574                 }
575         }
576
577         if (notification->content != NULL)
578         {
579                 free(notification->content);
580         }
581
582         notification->content = content_dup;
583
584         return UI_NOTIFICATION_ERROR_NONE;
585 }
586
587 int ui_notification_get_content(ui_notification_h notification, char **content)
588 {
589         char *content_dup = NULL;
590
591         if (notification == NULL || content == NULL)
592         {
593                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
594                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
595         }
596
597         if (notification->content != NULL)
598         {
599                 content_dup = strdup(notification->content);
600
601                 if (content_dup == NULL)
602                 {
603                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
604                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
605                 }
606         }
607
608         *content = content_dup;
609
610         return UI_NOTIFICATION_ERROR_NONE;
611 }
612
613
614 int ui_notification_set_service(ui_notification_h notification, service_h service)
615 {
616         int retcode;
617         service_h service_dup = NULL;
618
619         if (notification == NULL)
620         {
621                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
622                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
623         }
624
625         if (service != NULL)
626         {
627                 retcode = service_clone(&service_dup, service);
628
629                 if (retcode != SERVICE_ERROR_NONE)
630                 {
631                         if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
632                         {
633                                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
634                                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
635                         }
636                         else
637                         {
638                                 LOGE("INVALID_PARAMETER(0x%08x) : invalid service handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
639                                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
640                         }
641                 }
642         }
643
644         if (notification->service != NULL)
645         {
646                 service_destroy(notification->service);
647         }
648
649         notification->service = service_dup;
650
651         return UI_NOTIFICATION_ERROR_NONE;
652 }
653
654 int ui_notification_get_service(ui_notification_h notification, service_h *service)
655 {
656         int retcode;
657         service_h service_dup = NULL;
658
659         if (notification == NULL || service == NULL)
660         {
661                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
662                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
663         }
664
665         if (notification->service != NULL)
666         {
667                 retcode = service_clone(&service_dup, notification->service);
668
669                 if (retcode != SERVICE_ERROR_NONE)
670                 {
671                         if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
672                         {
673                                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
674                                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
675                         }
676                         else
677                         {
678                                 LOGE("INVALID_PARAMETER(0x%08x) : invalid service handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
679                                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
680                         }
681                 }
682         }
683
684         *service = service_dup;
685
686         return UI_NOTIFICATION_ERROR_NONE;
687 }
688
689 int ui_notification_set_sound(ui_notification_h notification, const char *path)
690 {
691         char *path_dup = NULL;
692
693         if (notification == NULL)
694         {
695                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
696                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
697         }
698
699         if (path != NULL)
700         {
701                 path_dup = strdup(path);
702
703                 if (path_dup == NULL)
704                 {
705                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
706                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
707                 }
708         }
709
710         if (notification->sound != NULL)
711         {
712                 free(notification->sound);
713         }
714
715         notification->sound = path_dup;
716
717         return UI_NOTIFICATION_ERROR_NONE;
718 }
719
720 int ui_notification_get_sound(ui_notification_h notification, char **path)
721 {
722         char *path_dup = NULL;
723
724         if (notification == NULL || path == NULL)
725         {
726                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
727                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
728         }
729
730         if (notification->sound != NULL)
731         {
732                 path_dup = strdup(notification->sound);
733
734                 if (path_dup == NULL)
735                 {
736                         LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
737                         *path = NULL;
738
739                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
740                 }
741         }
742
743         *path = path_dup;
744
745         return UI_NOTIFICATION_ERROR_NONE;
746 }
747
748 int ui_notification_set_vibration(ui_notification_h notification, bool value)
749 {
750         if (notification == NULL)
751         {
752                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
753                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
754         }
755
756         notification->vibration = value;
757
758         return UI_NOTIFICATION_ERROR_NONE;
759 }
760
761 int ui_notification_get_vibration(ui_notification_h notification, bool *value)
762 {
763         if (notification == NULL || value == NULL)
764         {
765                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
766                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
767         }
768
769         *value = notification->vibration;
770
771         return UI_NOTIFICATION_ERROR_NONE;
772 }
773
774 static int ui_notification_build_attributes(ui_notification_h notification)
775 {
776         bundle *service_data;
777
778         if (notification == NULL)
779         {
780                 LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
781                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
782         }
783
784         if (notification->icon != NULL)
785         {
786                 struct stat st;
787
788                 if (stat(notification->icon, &st) < 0)
789                 {
790                         LOGE("NO_SUCH_FILE(0x%08x) : invalid icon", UI_NOTIFICATION_ERROR_NO_SUCH_FILE);
791                         return UI_NOTIFICATION_ERROR_NO_SUCH_FILE;
792                 }
793
794                 notification_set_image(notification->raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, notification->icon);
795         }
796
797         if (notification->time != NULL)
798         {
799                 notification_set_time(notification->raw_handle, mktime(notification->time));
800         }
801
802         if (notification->title != NULL)
803         {
804                 notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, notification->title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
805         }
806
807         if (notification->content != NULL)
808         {
809                 notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, notification->content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
810         }
811
812         if (notification->service != NULL && service_to_bundle(notification->service, &service_data) == SERVICE_ERROR_NONE)
813         {
814                 notification_set_property(notification->raw_handle, 0);
815                 notification_set_execute_option(notification->raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
816         }
817         else
818         {
819                 notification_set_property(notification->raw_handle, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
820         }
821
822         if (notification->sound != NULL)
823         {
824                 struct stat st;
825
826                 if (stat(notification->sound, &st) < 0)
827                 {
828                         LOGE("NO_SUCH_FILE(0x%08x) : invalid sound file", UI_NOTIFICATION_ERROR_NO_SUCH_FILE);
829                         return UI_NOTIFICATION_ERROR_NO_SUCH_FILE;
830                 }
831                 notification_set_sound(notification->raw_handle, NOTIFICATION_SOUND_TYPE_USER_DATA, notification->sound);
832         }
833
834         if (notification->vibration)
835         {
836                 notification_set_vibration(notification->raw_handle, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
837         }
838
839         return UI_NOTIFICATION_ERROR_NONE;
840 }
841
842 int ui_notification_post(ui_notification_h notification)
843 {
844         int retcode;
845
846         if (notification == NULL)
847         {
848                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
849                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
850         }
851
852         if (notification->posted == true)
853         {
854                 LOGE("INVALID_STATE(0x%08x) : the notification was already posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
855                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
856         }
857
858         if (notification->ongoing == true)
859         {
860                 notification->raw_handle = notification_new(NOTIFICATION_TYPE_ONGOING, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
861         }
862         else
863         {
864                 notification->raw_handle = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
865         }
866
867         if (notification->raw_handle == NULL)
868         {
869                 LOGE("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
870                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
871         }
872
873         retcode = ui_notification_build_attributes(notification);
874
875         if (retcode != UI_NOTIFICATION_ERROR_NONE)
876         {
877                 return retcode;
878         }
879
880         retcode = ui_notification_error_handler(notification_insert(notification->raw_handle, NULL), __FUNCTION__, "failed to post a notification");
881
882         if (retcode == UI_NOTIFICATION_ERROR_NONE)
883         {
884                 notification->posted = true;
885         }
886
887         return retcode;
888 }
889
890 int ui_notification_update(ui_notification_h notification)
891 {
892         int retcode;
893
894         if (notification == NULL)
895         {
896                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
897                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
898         }
899
900         if (notification->posted == false)
901         {
902                 LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
903                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
904         }
905
906         if (notification->removed == true)
907         {
908                 LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", UI_NOTIFICATION_ERROR_INVALID_STATE);
909                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
910         }
911
912         retcode = ui_notification_build_attributes(notification);
913
914         if (retcode != UI_NOTIFICATION_ERROR_NONE)
915         {
916                 return retcode;
917         }
918
919         retcode = ui_notification_error_handler(notification_update(notification->raw_handle), __FUNCTION__, "failed to post a notification");
920
921         if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
922         {
923                 notification->removed = true;
924         }
925
926         return retcode;
927 }
928
929 int  ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value)
930 {
931         int retcode;
932
933         if (notification == NULL)
934         {
935                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
936                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
937         }
938
939         if (notification->raw_handle == NULL)
940         {
941                 LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
942                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
943         }
944
945         if (notification->posted == false)
946         {
947                 LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
948                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
949         }
950
951         if (notification->removed == true)
952         {
953                 LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", UI_NOTIFICATION_ERROR_INVALID_STATE);
954                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
955         }
956
957         if (value < 0)
958         {
959                 LOGE("INVALID_PARAMETER(0x%08x) : the value must be greater than or equal to zero.", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
960                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
961         }
962
963         switch (type)
964         {
965         case UI_NOTIFICATION_PROGRESS_TYPE_SIZE:
966                 retcode = ui_notification_error_handler(
967                         notification_update_size(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
968                         __FUNCTION__, "failed to update the progress");
969                 break;
970
971         case UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE:
972                 retcode = ui_notification_error_handler(
973                         notification_update_progress(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
974                         __FUNCTION__, "failed to update the progress");
975                 break;
976
977         default:
978                 LOGE("INVALID_PARAMETER(0x%08x) : invalid progress type", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
979                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
980         }
981
982         if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
983         {
984                 notification->removed = true;
985         }
986
987         return retcode;
988 }
989
990 int ui_notification_cancel(ui_notification_h notification)
991 {
992         int retcode;
993
994         if (notification == NULL)
995         {
996                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
997                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
998         }
999
1000         if (notification->raw_handle == NULL)
1001         {
1002                 LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
1003                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
1004         }
1005
1006         if (notification->posted == false)
1007         {
1008                 LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
1009                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
1010         }
1011
1012         if (notification->removed == true)
1013         {
1014                 LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", UI_NOTIFICATION_ERROR_INVALID_STATE);
1015                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
1016         }
1017
1018         retcode = ui_notification_error_handler(notification_delete(notification->raw_handle), __FUNCTION__, "failed to cancel the notification");
1019
1020         if (retcode == UI_NOTIFICATION_ERROR_NONE)
1021         {
1022                 notification->removed = true;
1023         }
1024
1025         return retcode;
1026 }
1027
1028 void ui_notification_cancel_all(void)
1029 {
1030         notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NONE);
1031 }
1032
1033 void ui_notification_cancel_all_by_type(bool ongoing)
1034 {
1035         notification_type_e type = NOTIFICATION_TYPE_NONE;
1036
1037         if (ongoing)
1038                 type = NOTIFICATION_TYPE_ONGOING;
1039         else
1040                 type = NOTIFICATION_TYPE_NOTI;
1041
1042         notification_delete_all_by_type(NULL, type);
1043 }
1044
1045 void ui_notification_cancel_all_by_package(const char *package, bool ongoing)
1046 {
1047         notification_type_e type = NOTIFICATION_TYPE_NONE;
1048
1049         if (ongoing)
1050                 type = NOTIFICATION_TYPE_ONGOING;
1051         else
1052                 type = NOTIFICATION_TYPE_NOTI;
1053
1054         notification_delete_all_by_type(package, type);
1055 }
1056
1057 int ui_notification_cancel_all_by_app_id(const char *app_id, bool ongoing)
1058 {
1059         notification_type_e type = NOTIFICATION_TYPE_NONE;
1060
1061         if (app_id == NULL)
1062         {
1063                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
1064                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
1065         }
1066
1067         if (ongoing)
1068                 type = NOTIFICATION_TYPE_ONGOING;
1069         else
1070                 type = NOTIFICATION_TYPE_NOTI;
1071
1072         notification_delete_all_by_type(app_id, type);
1073
1074         return UI_NOTIFICATION_ERROR_NONE;
1075 }
1076
1077 static bool ui_notification_package_equal(notification_h handle)
1078 {
1079         char *package = NULL;
1080         char *handle_package = NULL;
1081         char cmdline[512] = {0,};
1082         char buf[64] = {0,};
1083
1084         if (notification_get_pkgname(handle, &handle_package))
1085         {
1086                 return false;
1087         }
1088
1089         if (app_get_package(&package))
1090         {
1091                 int ret = 0;
1092                 int fd = -1;
1093                 int pid = getpid();
1094
1095                 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
1096
1097                 fd = open(buf, O_RDONLY);
1098                 if (fd < 0) {
1099                         return false;
1100                 }
1101
1102                 ret = read(fd, cmdline, sizeof(cmdline) - 1);
1103                 if (ret <= 0) {
1104                         close(fd);
1105                         return false;
1106                 }
1107
1108                 cmdline[ret] = 0;
1109                 close(fd);
1110
1111                 if (strlen(cmdline) == strlen(handle_package))
1112                 {
1113                         if (!strncmp(cmdline, handle_package, strlen(cmdline)))
1114                         {
1115                                 return true;
1116                         }
1117                 }
1118         }
1119         else
1120         {
1121                 if (strlen(package) == strlen(handle_package))
1122                 {
1123                                 if (!strncmp(package, handle_package, strlen(package)))
1124                                 {
1125                                         return true;
1126                                 }
1127                 }
1128         }
1129
1130         return false;
1131 }
1132
1133 int ui_notification_foreach_notification_posted(bool ongoing, ui_notification_cb callback, void *user_data)
1134 {
1135         notification_list_h raw_handle_list;
1136         notification_h raw_handle;
1137         notification_type_e notification_type = ongoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
1138         ui_notification_h notification = NULL;
1139         bool iterate_next = true;
1140
1141         if (callback == NULL)
1142         {
1143                 LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
1144                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
1145         }
1146
1147         if (notification_get_grouping_list(notification_type, -1, &raw_handle_list))
1148         {
1149                 LOGE("DB_FAILED(0x%08x) : failed to get a notification list", UI_NOTIFICATION_ERROR_DB_FAILED);
1150                 return UI_NOTIFICATION_ERROR_DB_FAILED;
1151         }
1152
1153         while (raw_handle_list != NULL)
1154         {
1155                 raw_handle = notification_list_get_data(raw_handle_list);
1156
1157                 if (raw_handle != NULL && ui_notification_package_equal(raw_handle))
1158                 {
1159                         if (!ui_notification_construct(ongoing, raw_handle, &notification))
1160                         {
1161                                 iterate_next = callback(notification, user_data);
1162
1163                                 ui_notification_destroy(notification);
1164
1165                                 if (iterate_next == false)
1166                                 {
1167                                         break;
1168                                 }
1169                         }
1170                 }
1171
1172                 raw_handle_list = notification_list_get_next(raw_handle_list);
1173         }
1174
1175         notification_free_list(raw_handle_list);
1176
1177         return UI_NOTIFICATION_ERROR_NONE;
1178 }
1179