0129eb84f330765d612c73f301b06c34e1f80d41
[framework/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
24 #include <dlog.h>
25 #include <notification.h>
26
27 #include <app.h>
28 #include <app_service_private.h>
29
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #endif
33
34 #define LOG_TAG "TIZEN_N_UI_NOTIFICATION"
35
36 struct ui_notification_s {
37         notification_h raw_handle;
38         bool ongoing;
39         bool posted;
40         bool removed;
41         char *icon;
42         struct tm *time;
43         char *title;
44         char *content;
45         service_h service;
46 };
47
48 static int ui_notification_error_handler(int error, const char *func, const char *on_error)
49 {
50         int retcode;
51         char *error_msg;
52
53         switch (error)
54         {
55         case NOTIFICATION_ERROR_NONE:
56                 retcode = UI_NOTIFICATION_ERROR_NONE;
57                 break;
58
59         case NOTIFICATION_ERROR_INVALID_DATA:
60                 retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
61                 error_msg = "INVALID_PARAMETER";
62                 break;
63
64         case NOTIFICATION_ERROR_NO_MEMORY:
65                 retcode = UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
66                 error_msg = "OUT_OF_MEMORY";
67                 break;
68
69         case NOTIFICATION_ERROR_FROM_DB:
70                 retcode = UI_NOTIFICATION_ERROR_DB_FAILED;
71                 error_msg = "DB_FAILED";
72                 break;          
73
74         case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
75         case NOTIFICATION_ERROR_NOT_EXIST_ID:
76                 retcode = UI_NOTIFICATION_ERROR_INVALID_STATE;
77                 error_msg = "INVALID_STATE";
78                 break;
79
80         default:
81                 retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
82                 error_msg = "INVALID_PARAMETER";
83         }
84
85         if (retcode != UI_NOTIFICATION_ERROR_NONE)
86         {
87                 LOGE("[%s] %s(0x%08x) : %s", func, error_msg, retcode, on_error);
88         }
89
90         return retcode;
91 }
92
93
94 int ui_notification_create(bool ongoing, ui_notification_h *notification)
95 {
96         ui_notification_h notification_out;
97
98         if (notification == NULL)
99         {
100                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
101                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
102         }
103
104         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
105
106         if (notification_out == NULL)
107         {
108                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
109                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
110         }
111         
112         notification_out->raw_handle = NULL;
113         notification_out->ongoing = ongoing;
114         notification_out->posted = false;
115         notification_out->removed = false;
116         notification_out->icon = NULL;
117         notification_out->time = NULL;
118         notification_out->title = NULL;
119         notification_out->content = NULL;
120         notification_out->service = NULL;
121         
122         *notification = notification_out;
123
124         return UI_NOTIFICATION_ERROR_NONE;
125 }
126
127 static int ui_notification_construct(bool ongoing, notification_h raw_handle, ui_notification_h *notification)
128 {
129         int retcode;
130         ui_notification_h notification_out;
131         char *icon;
132         time_t time;
133         char *title;
134         char *content;
135         bundle *service_data;
136
137         if (notification == NULL)
138         {
139                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
140                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
141         }
142
143         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
144
145         if (notification_out == NULL)
146         {
147                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
148                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
149         }
150
151         retcode = ui_notification_error_handler(notification_clone(raw_handle, &(notification_out->raw_handle)),\
152                                  __FUNCTION__, "failed to clone the notification handle");
153
154         if (retcode != NOTIFICATION_ERROR_NONE)
155         {
156                 return retcode;
157         }
158         
159         notification_out->ongoing = ongoing;
160
161         notification_out->posted = true;
162
163         notification_out->removed = false;
164
165         if (!notification_get_image(raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, &icon))
166         {
167                 notification_out->icon = icon;
168         }
169
170         if (!notification_get_time(raw_handle, &time))
171         {
172                 notification_out->time = malloc(sizeof(struct tm));
173                 
174                 if (notification_out->time == NULL)
175                 {
176                         ui_notification_destroy(notification_out);
177                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
178                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
179                 }
180
181                 localtime_r(&time, notification_out->time);
182         }
183
184         if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, &title))
185         {
186                 notification_out->title = title;
187         }
188
189         if (!   notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &content))
190         {
191                 notification_out->content = content;
192         }
193
194         if (!notification_get_execute_option(raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, &service_data))
195         {
196                 service_h service;
197
198                 if (!service_create_request(service_data, &service))
199                 {
200                         notification_out->service = service;
201                 }
202         }
203
204         *notification = notification_out;
205
206         return UI_NOTIFICATION_ERROR_NONE;
207 }
208
209 int ui_notification_destroy(ui_notification_h notification)
210 {
211         if (notification == NULL)
212         {
213                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
214                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
215         }
216
217         if (notification->raw_handle)
218                 notification_free(notification->raw_handle);
219
220         if (notification->icon)
221                 free(notification->icon);
222
223         if (notification->time)
224                 free(notification->time);
225
226         if (notification->title)
227                 free(notification->title);
228
229         if (notification->content)
230                 free(notification->content);
231
232         if (notification->service)
233                 service_destroy(notification->service);
234
235         free(notification);
236
237         return UI_NOTIFICATION_ERROR_NONE;
238 }
239
240 int ui_notification_clone(ui_notification_h *clone, ui_notification_h notification)
241 {
242         ui_notification_h notification_out;
243         int retcode;
244
245         if (clone == NULL || notification == NULL)
246         {
247                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
248                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
249         }
250
251         notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
252
253         if (notification->raw_handle != NULL)
254         {
255                 retcode = notification_clone(notification->raw_handle, &(notification_out->raw_handle));
256
257                 if (retcode)
258                 {
259                         return ui_notification_error_handler(retcode, __FUNCTION__, "failed to clone the handle");
260                 }
261         }
262
263         notification_out->ongoing = notification->ongoing;
264
265         notification_out->posted = notification->posted;
266
267         notification_out->removed = notification->removed;
268
269         if (notification->icon)
270         {
271                 notification_out->icon = strdup(notification->icon);
272         }
273
274         if (notification->time)
275         {
276                 notification_out->time = malloc(sizeof(struct tm));
277                 if (notification_out->time != NULL)
278                 {
279                         memcpy(notification_out->time, notification->time, sizeof(struct tm));
280                 }
281         }
282
283         if (notification->title)
284         {
285                 notification_out->title = strdup(notification->title);
286         }
287
288         if (notification->content)
289         {
290                 notification_out->content = strdup(notification->content);
291         }
292
293         if (notification->service)
294         {
295                 service_clone(&(notification_out->service), notification->service);
296         }
297
298         *clone = notification_out;
299
300         return UI_NOTIFICATION_ERROR_NONE;
301 }
302
303 int ui_notification_is_ongoing(ui_notification_h notification, bool *ongoing)
304 {
305         if (notification == NULL || ongoing == NULL)
306         {
307                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
308                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
309         }
310
311         *ongoing = notification->ongoing;
312
313         return UI_NOTIFICATION_ERROR_NONE;
314 }
315
316 int ui_notification_set_icon(ui_notification_h notification, const char *path)
317 {
318         char *path_dup = NULL;
319
320         if (notification == NULL)
321         {
322                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
323                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
324         }
325
326         if (path != NULL)
327         {
328                 path_dup = strdup(path);
329
330                 if (path_dup == NULL)
331                 {
332                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
333                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
334                 }
335         }
336
337         if (notification->icon != NULL)
338         {
339                 free(notification->icon);
340         }
341
342         notification->icon = path_dup;
343
344         return UI_NOTIFICATION_ERROR_NONE;
345 }
346
347 int ui_notification_get_icon(ui_notification_h notification, char **path)
348 {
349         char *path_dup = NULL;
350
351         if (notification == NULL || path == NULL)
352         {
353                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
354                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
355         }
356
357         if (notification->icon != NULL)
358         {
359                 path_dup = strdup(notification->icon);
360
361                 if (path_dup == NULL)
362                 {
363                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
364                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
365                 }
366         }
367
368         *path = path_dup;
369
370         return UI_NOTIFICATION_ERROR_NONE;
371 }
372
373 int ui_notification_set_time(ui_notification_h notification, struct tm *time)
374 {
375         struct tm *time_dup = NULL;
376
377         if (notification == NULL)
378         {
379                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
380                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
381         }
382
383         if (time != NULL)
384         {
385                 time_dup = malloc(sizeof(struct tm));
386
387                 if (time_dup == NULL)
388                 {
389                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
390                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
391                 }
392
393                 memcpy(time_dup, time, sizeof(struct tm));
394         }
395
396         if (notification->time != NULL)
397         {
398                 free(notification->time);
399         }
400
401         notification->time = time_dup;
402
403         return UI_NOTIFICATION_ERROR_NONE;
404 }
405
406 int ui_notification_get_time(ui_notification_h notification, struct tm **time)
407 {
408         struct tm *time_dup = NULL;
409
410         if (notification == NULL || time == NULL)
411         {
412                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
413                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
414         }
415
416         if (notification->time != NULL)
417         {
418                 time_dup = malloc(sizeof(struct tm));
419
420                 if (time_dup == NULL)
421                 {
422                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
423                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
424                 }
425         
426                 memcpy(time_dup, notification->time, sizeof(struct tm));
427         }
428
429         *time = time_dup;
430
431         return UI_NOTIFICATION_ERROR_NONE;
432 }
433
434 int ui_notification_set_title(ui_notification_h notification, const char *title)
435 {
436         char *title_dup = NULL;
437
438         if (notification == NULL)
439         {
440                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
441                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
442         }
443
444         if (title != NULL)
445         {
446                 title_dup = strdup(title);
447
448                 if (title_dup == NULL)
449                 {
450                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
451                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
452                 }
453         }
454
455         if (notification->title != NULL)
456         {
457                 free(notification->title);
458         }
459
460         notification->title = title_dup;
461
462         return UI_NOTIFICATION_ERROR_NONE;
463 }
464
465 int ui_notification_get_title(ui_notification_h notification, char **title)
466 {
467         char *title_dup = NULL;
468
469         if (notification == NULL || title == NULL)
470         {
471                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
472                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
473         }
474
475         if (notification->title != NULL)
476         {
477                 title_dup = strdup(notification->title);
478
479                 if (title_dup == NULL)
480                 {
481                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
482                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
483                 }
484         }
485
486         *title = title_dup;
487
488         return UI_NOTIFICATION_ERROR_NONE;
489 }
490
491
492 int ui_notification_set_content(ui_notification_h notification, const char *content)
493 {
494         char *content_dup = NULL;
495
496         if (notification == NULL)
497         {
498                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
499                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
500         }
501
502         if (content != NULL)
503         {
504                 content_dup = strdup(content);
505
506                 if (content_dup == NULL)
507                 {
508                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
509                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
510                 }
511         }
512
513         if (notification->content != NULL)
514         {
515                 free(notification->content);
516         }
517
518         notification->content = content_dup;
519
520         return UI_NOTIFICATION_ERROR_NONE;
521 }
522
523 int ui_notification_get_content(ui_notification_h notification, char **content)
524 {
525         char *content_dup = NULL;
526
527         if (notification == NULL || content == NULL)
528         {
529                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
530                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
531         }
532
533         if (notification->content != NULL)
534         {
535                 content_dup = strdup(notification->content);
536
537                 if (content_dup == NULL)
538                 {
539                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
540                         return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
541                 }
542         }
543
544         *content = content_dup;
545
546         return UI_NOTIFICATION_ERROR_NONE;
547 }
548
549
550 int ui_notification_set_service(ui_notification_h notification, service_h service)
551 {
552         int retcode;
553         service_h service_dup = NULL;
554
555         if (notification == NULL)
556         {
557                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
558                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
559         }
560
561         if (service != NULL)
562         {
563                 retcode = service_clone(&service_dup, service);
564
565                 if (retcode != SERVICE_ERROR_NONE)
566                 {
567                         if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
568                         {
569                                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
570                                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
571                         }
572                         else
573                         {
574                                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
575                                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
576                         }
577                 }
578         }
579
580         if (notification->service != NULL)
581         {
582                 service_destroy(notification->service);
583         }
584
585         notification->service = service_dup;
586
587         return UI_NOTIFICATION_ERROR_NONE;
588 }
589
590 int ui_notification_get_service(ui_notification_h notification, service_h *service)
591 {
592         int retcode;
593         service_h service_dup = NULL;
594
595         if (notification == NULL || service == NULL)
596         {
597                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
598                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
599         }
600
601         if (notification->service != NULL)
602         {
603                 retcode = service_clone(&service_dup, notification->service);
604
605                 if (retcode != SERVICE_ERROR_NONE)
606                 {
607                         if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
608                         {
609                                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
610                                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
611                         }
612                         else
613                         {
614                                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
615                                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
616                         }
617                 }
618         }
619
620         *service = service_dup;
621
622         return UI_NOTIFICATION_ERROR_NONE;
623 }
624
625 static int ui_notification_build_attributes(ui_notification_h notification)
626 {
627         bundle *service_data;
628
629         if (notification == NULL)
630         {
631                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
632                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
633         }
634
635         if (notification->icon != NULL)
636         {
637                 struct stat st;
638         
639                 if (stat(notification->icon, &st) < 0)
640                 {
641                         LOGE("[%s] NO_SUCH_FILE(0x%08x) : invalid icon", __FUNCTION__, UI_NOTIFICATION_ERROR_NO_SUCH_FILE);
642                         return UI_NOTIFICATION_ERROR_NO_SUCH_FILE;
643                 }
644
645                 notification_set_image(notification->raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, notification->icon);
646         }
647
648         if (notification->time != NULL)
649         {
650                 notification_set_time(notification->raw_handle, mktime(notification->time));
651         }
652
653         if (notification->title != NULL)
654         {
655                 notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, notification->title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
656         }
657
658         if (notification->content != NULL)
659         {
660                 notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, notification->content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
661         }
662
663         if (notification->service != NULL && service_to_bundle(notification->service, &service_data) == SERVICE_ERROR_NONE)
664         {
665                 notification_set_property(notification->raw_handle, 0);
666                 notification_set_execute_option(notification->raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
667         }
668         else
669         {
670                 notification_set_property(notification->raw_handle, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
671         }
672
673         return UI_NOTIFICATION_ERROR_NONE;
674 }
675
676 int ui_notification_post(ui_notification_h notification)
677 {
678         int retcode;
679
680         if (notification == NULL)
681         {
682                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
683                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
684         }
685
686         if (notification->posted == true)
687         {
688                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was already posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
689                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
690         }
691
692         // STEP 1: notification handle
693         if (notification->ongoing == true)
694         {
695                 notification->raw_handle = notification_new(NOTIFICATION_TYPE_ONGOING, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
696         }
697         else
698         {
699                 notification->raw_handle = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
700         }
701
702         if (notification->raw_handle == NULL)
703         {
704                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
705                 return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
706         }
707
708         retcode = ui_notification_build_attributes(notification);
709
710         if (retcode != UI_NOTIFICATION_ERROR_NONE)
711         {
712                 return retcode;
713         }
714
715         retcode = ui_notification_error_handler(notification_insert(notification->raw_handle, NULL), __FUNCTION__, "failed to post a notification");
716
717         if (retcode == UI_NOTIFICATION_ERROR_NONE)
718         {
719                 notification->posted = true;
720         }
721
722         return retcode;
723 }
724
725 int ui_notification_update(ui_notification_h notification)
726 {
727         int retcode;
728
729         if (notification == NULL)
730         {
731                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
732                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
733         }
734
735         if (notification->posted == false)
736         {
737                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
738                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
739         }
740
741         if (notification->removed == true)
742         {
743                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
744                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
745         }
746
747         retcode = ui_notification_build_attributes(notification);
748
749         if (retcode != UI_NOTIFICATION_ERROR_NONE)
750         {
751                 return retcode;
752         }
753
754         retcode = ui_notification_error_handler(notification_update(notification->raw_handle), __FUNCTION__, "failed to post a notification");
755
756         if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
757         {
758                 notification->removed = true;
759         }
760
761         return retcode;
762 }
763
764 int  ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value)
765 {
766         int retcode;
767
768         if (notification == NULL)
769         {
770                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
771                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
772         }
773
774         if (notification->raw_handle == NULL)
775         {
776                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
777                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
778         }
779
780         if (notification->posted == false)
781         {
782                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
783                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
784         }
785
786         if (notification->removed == true)
787         {
788                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
789                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
790         }
791
792         if (value < 0)
793         {
794                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : the value must be greater than or equal to zero.", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
795                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
796         }
797
798         switch (type)
799         {
800         case UI_NOTIFICATION_PROGRESS_TYPE_SIZE:
801                 retcode = ui_notification_error_handler(
802                         notification_update_size(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
803                         __FUNCTION__, "failed to update the progress");
804                 break;
805                 
806         case UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE:
807                 retcode = ui_notification_error_handler(
808                         notification_update_progress(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
809                         __FUNCTION__, "failed to update the progress");
810                 break;
811
812         default:
813                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid progress type", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
814                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
815         }
816
817         if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
818         {
819                 notification->removed = true;
820         }
821
822         return retcode;
823 }
824
825 int ui_notification_cancel(ui_notification_h notification)
826 {
827         int retcode;
828
829         if (notification == NULL)
830         {
831                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
832                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
833         }
834
835         if (notification->raw_handle == NULL)
836         {
837                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
838                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
839         }
840
841         if (notification->posted == false)
842         {
843                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
844                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
845         }
846
847         if (notification->removed == true)
848         {
849                 LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
850                 return UI_NOTIFICATION_ERROR_INVALID_STATE;
851         }
852
853         retcode = ui_notification_error_handler(notification_delete(notification->raw_handle), __FUNCTION__, "failed to cancel the notification");
854
855         if (retcode == UI_NOTIFICATION_ERROR_NONE)
856         {
857                 notification->removed = true;
858         }
859
860         return retcode;
861 }
862
863 void ui_notification_cancel_all(void)
864 {
865         notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NONE);
866 }
867
868 static bool ui_notification_package_equal(notification_h handle)
869 {
870         char *package = NULL;
871         char *handle_package = NULL;
872
873         if (app_get_package(&package))
874         {
875                 return false;
876         }
877
878         if (notification_get_pkgname(handle, &handle_package))
879         {
880                 return false;
881         }
882
883         if (strlen(package) == strlen(handle_package))
884         {
885                 if (!strncmp(package, handle_package, strlen(package)))
886                 {
887                         return true;
888                 }
889         }
890
891         return false;
892 }
893
894 int ui_notification_foreach_notification_posted(bool ongoing, ui_notification_cb callback, void *user_data)
895 {
896         notification_list_h raw_handle_list;
897         notification_h raw_handle;
898         notification_type_e notification_type = ongoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
899         ui_notification_h notification = NULL;
900         bool iterate_next = true;
901
902         if (callback == NULL)
903         {
904                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
905                 return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
906         }
907
908         if (notification_get_grouping_list(notification_type, -1, &raw_handle_list))
909         {
910                 LOGE("[%s] DB_FAILED(0x%08x) : failed to get a notification list", __FUNCTION__, UI_NOTIFICATION_ERROR_DB_FAILED);
911                 return UI_NOTIFICATION_ERROR_DB_FAILED;
912         }
913
914         while (raw_handle_list != NULL)
915         {
916                 raw_handle = notification_list_get_data(raw_handle_list);
917
918                 if (raw_handle != NULL && ui_notification_package_equal(raw_handle))
919                 {
920                         if (!ui_notification_construct(ongoing, raw_handle, &notification))
921                         {
922                                 iterate_next = callback(notification, user_data);
923
924                                 ui_notification_destroy(notification);
925
926                                 if (iterate_next == false)
927                                 {
928                                         break;
929                                 }
930                         }
931                 }
932
933                 raw_handle_list = notification_list_get_next(raw_handle_list);
934         }
935
936         notification_free_list(raw_handle_list);
937
938         return UI_NOTIFICATION_ERROR_NONE;
939 }
940