1. new public API set for setting/getting permissions of the notification.
[platform/core/api/notification.git] / src / notification_noti.c
1 /*
2  *  libnotification
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include <vconf.h>
27 #include <Ecore.h>
28 #include <Elementary.h>
29 #include <Eina.h>
30
31 #include <notification.h>
32 #include <notification_db.h>
33 #include <notification_noti.h>
34 #include <notification_debug.h>
35 #include <notification_private.h>
36
37 #define NOTI_BURST_DELETE_UNIT 10
38 static Eina_List *toast_list;
39 static Eina_List *toast_popup;
40
41 static void __free_and_set(void **target_ptr, void *new_ptr) {
42         if (target_ptr != NULL) {
43                 if (*target_ptr != NULL) {
44                         free(*target_ptr);
45                 }
46                 *target_ptr = new_ptr;
47         }
48 }
49
50 static int _notification_noti_bind_query_text(sqlite3_stmt * stmt, const char *name,
51                                          const char *str)
52 {
53         int ret = 0;
54         int index = 0;
55
56         index = sqlite3_bind_parameter_index(stmt, name);
57         if (index == 0) {
58                 NOTIFICATION_ERR("Insert : invalid column name");
59                 return NOTIFICATION_ERROR_FROM_DB;
60         }
61
62         ret =
63             sqlite3_bind_text(stmt, index, NOTIFICATION_CHECK_STR(str), -1,
64                               SQLITE_STATIC);
65         if (ret != SQLITE_OK) {
66                 NOTIFICATION_ERR("Insert text : %s",
67                                  NOTIFICATION_CHECK_STR(str));
68                 return NOTIFICATION_ERROR_FROM_DB;
69         }
70
71         return NOTIFICATION_ERROR_NONE;
72 }
73
74 static int _notification_noti_bind_query_double(sqlite3_stmt * stmt, const char *name,
75                                          double val)
76 {
77         int ret = 0;
78         int index = 0;
79
80         index = sqlite3_bind_parameter_index(stmt, name);
81         if (index == 0) {
82                 NOTIFICATION_ERR("Insert : invalid column name");
83                 return NOTIFICATION_ERROR_FROM_DB;
84         }
85
86         ret = sqlite3_bind_double(stmt, index, val);
87         if (ret != SQLITE_OK) {
88                 NOTIFICATION_ERR("Insert double : %f", val);
89                 return NOTIFICATION_ERROR_FROM_DB;
90         }
91
92         return NOTIFICATION_ERROR_NONE;
93 }
94
95 static int _notification_noti_check_priv_id(notification_h noti, sqlite3 * db)
96 {
97         int result = 0;
98         int ret = NOTIFICATION_ERROR_NONE;
99         char *query = NULL;
100         sqlite3_stmt *stmt = NULL;
101
102         /* Make query to check priv_id exist */
103         query = sqlite3_mprintf("SELECT count(*) FROM noti_list WHERE caller_pkgname = '%s' AND priv_id = %d",
104                  noti->caller_pkgname, noti->priv_id);
105         if (query == NULL) {
106                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
107                 goto err;
108         }
109
110         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
111         if (ret != SQLITE_OK) {
112                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
113                                  sqlite3_errmsg(db));
114                 ret = NOTIFICATION_ERROR_FROM_DB;
115                 goto err;
116         }
117
118         ret = sqlite3_step(stmt);
119         if (ret == SQLITE_ROW) {
120                 result = sqlite3_column_int(stmt, 0);
121         } else {
122                 result = 0;
123         }
124
125         sqlite3_finalize(stmt);
126
127         /* If result > 0, there is priv_id in DB */
128         if (result > 0) {
129                 ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
130         }
131
132 err:
133         if (query) {
134                 sqlite3_free(query);
135         }
136
137         return ret;
138 }
139
140 static int _notification_noti_get_internal_group_id_by_priv_id(const char *pkgname,
141                                                                int priv_id,
142                                                                sqlite3 * db)
143 {
144         char *query = NULL;
145         sqlite3_stmt *stmt = NULL;
146         int ret = NOTIFICATION_ERROR_NONE, result = 0;
147
148         query = sqlite3_mprintf("SELECT internal_group_id FROM noti_list WHERE caller_pkgname = '%s' AND priv_id = %d",
149                  pkgname, priv_id);
150         if (query == NULL) {
151                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
152                 goto err;
153         }
154
155         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
156         if (ret != SQLITE_OK) {
157                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
158                                  sqlite3_errmsg(db));
159                 ret = NOTIFICATION_ERROR_FROM_DB;
160                 goto err;
161         }
162
163         ret = sqlite3_step(stmt);
164         if (ret == SQLITE_ROW) {
165                 result = sqlite3_column_int(stmt, 0);
166         } else {
167                 result = 0;
168         }
169
170 err:
171         if (stmt) {
172                 sqlite3_finalize(stmt);
173         }
174
175         if (query) {
176                 sqlite3_free(query);
177         }
178
179         if (ret != NOTIFICATION_ERROR_NONE) {
180                 NOTIFICATION_ERR("failed to internal group ID:%d", ret);
181         }
182
183         return result;
184 }
185
186 static int _insertion_query_create(notification_h noti, char **query)
187 {
188         int b_encode_len = 0;
189         char *args = NULL;
190         char *group_args = NULL;
191         char *b_image_path = NULL;
192         char *b_execute_option = NULL;
193         char *b_service_responding = NULL;
194         char *b_service_single_launch = NULL;
195         char *b_service_multi_launch = NULL;
196         char *b_text = NULL;
197         char *b_key = NULL;
198         char *b_format_args = NULL;
199         int flag_simmode = 0;
200
201         if (query == NULL) {
202                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
203         }
204
205         /* Decode bundle to insert DB */
206         if (noti->args) {
207                 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
208         }
209         if (noti->group_args) {
210                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
211                               &b_encode_len);
212         }
213
214         if (noti->b_execute_option) {
215                 bundle_encode(noti->b_execute_option,
216                               (bundle_raw **) & b_execute_option, &b_encode_len);
217         }
218         if (noti->b_service_responding) {
219                 bundle_encode(noti->b_service_responding,
220                               (bundle_raw **) & b_service_responding, &b_encode_len);
221         }
222         if (noti->b_service_single_launch) {
223                 bundle_encode(noti->b_service_single_launch,
224                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
225         }
226         if (noti->b_service_multi_launch) {
227                 bundle_encode(noti->b_service_multi_launch,
228                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
229         }
230
231         if (noti->b_text) {
232                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
233         }
234         if (noti->b_key) {
235                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
236         }
237         if (noti->b_format_args) {
238                 bundle_encode(noti->b_format_args,
239                               (bundle_raw **) & b_format_args, &b_encode_len);
240         }
241
242         if (noti->b_image_path) {
243                 bundle_encode(noti->b_image_path,
244                               (bundle_raw **) & b_image_path, &b_encode_len);
245         }
246
247         /* Check only simmode property is enable */
248         if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
249                 flag_simmode = 1;
250         }
251
252         /* Make query */
253         *query = sqlite3_mprintf("INSERT INTO noti_list ("
254                  "type, "
255                  "layout, "
256                  "caller_pkgname, launch_pkgname, "
257                  "image_path, "
258                  "group_id, internal_group_id, priv_id, "
259                  "title_key, "
260                  "b_text, b_key, tag, b_format_args, num_format_args, "
261                  "text_domain, text_dir, "
262                  "time, insert_time, "
263                  "args, group_args, "
264                  "b_execute_option, "
265                  "b_service_responding, b_service_single_launch, b_service_multi_launch, "
266                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
267                  "flags_for_property, flag_simmode, display_applist, "
268                  "progress_size, progress_percentage) values ("
269                  "%d, "
270                  "%d, "
271                  "'%s', '%s', "
272                  "'%s', "
273                  "%d, %d, %d, "
274                  "$title_key, "
275                  "'%s', '%s', $tag, '%s', %d, "
276                  "'%s', '%s', "
277                  "%d, %d, "
278                  "'%s', '%s', "
279                  "'%s', "
280                  "'%s', '%s', '%s', "
281                  "%d, '%s', %d, '%s', %d, %d, %d, %d,"
282                  "%d, %d, %d, "
283                  "$progress_size, $progress_percentage)",
284                  noti->type,
285                  noti->layout,
286                  NOTIFICATION_CHECK_STR(noti->caller_pkgname),
287                  NOTIFICATION_CHECK_STR(noti->launch_pkgname),
288                  NOTIFICATION_CHECK_STR(b_image_path), noti->group_id,
289                  noti->internal_group_id, noti->priv_id,
290                  NOTIFICATION_CHECK_STR(b_text), NOTIFICATION_CHECK_STR(b_key),
291                  NOTIFICATION_CHECK_STR(b_format_args), noti->num_format_args,
292                  NOTIFICATION_CHECK_STR(noti->domain),
293                  NOTIFICATION_CHECK_STR(noti->dir), (int)noti->time,
294                  (int)noti->insert_time, NOTIFICATION_CHECK_STR(args),
295                  NOTIFICATION_CHECK_STR(group_args),
296                  NOTIFICATION_CHECK_STR(b_execute_option),
297                  NOTIFICATION_CHECK_STR(b_service_responding),
298                  NOTIFICATION_CHECK_STR(b_service_single_launch),
299                  NOTIFICATION_CHECK_STR(b_service_multi_launch),
300                  noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
301                  noti->vibration_type,
302                  NOTIFICATION_CHECK_STR(noti->vibration_path),
303                  noti->led_operation,
304                  noti->led_argb,
305                  noti->led_on_ms,
306                  noti->led_off_ms,
307                  noti->flags_for_property, flag_simmode, noti->display_applist);
308
309         /* Free decoded data */
310         if (args) {
311                 free(args);
312         }
313         if (group_args) {
314                 free(group_args);
315         }
316
317         if (b_execute_option) {
318                 free(b_execute_option);
319         }
320         if (b_service_responding) {
321                 free(b_service_responding);
322         }
323         if (b_service_single_launch) {
324                 free(b_service_single_launch);
325         }
326         if (b_service_multi_launch) {
327                 free(b_service_multi_launch);
328         }
329
330         if (b_text) {
331                 free(b_text);
332         }
333         if (b_key) {
334                 free(b_key);
335         }
336         if (b_format_args) {
337                 free(b_format_args);
338         }
339
340         if (b_image_path) {
341                 free(b_image_path);
342         }
343
344         if (*query == NULL) {
345                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
346         }
347
348         return NOTIFICATION_ERROR_NONE;
349 }
350
351
352 static int _update_query_create(notification_h noti, char **query)
353 {
354         int b_encode_len = 0;
355         char *args = NULL;
356         char *group_args = NULL;
357         char *b_image_path = NULL;
358         char *b_execute_option = NULL;
359         char *b_service_responding = NULL;
360         char *b_service_single_launch = NULL;
361         char *b_service_multi_launch = NULL;
362         char *b_text = NULL;
363         char *b_key = NULL;
364         char *b_format_args = NULL;
365         int flag_simmode = 0;
366
367         if (query == NULL) {
368                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
369         }
370
371         /* Decode bundle to update DB */
372         if (noti->args) {
373                 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
374         }
375         if (noti->group_args) {
376                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
377                               &b_encode_len);
378         }
379
380         if (noti->b_execute_option) {
381                 bundle_encode(noti->b_execute_option,
382                               (bundle_raw **) & b_execute_option, &b_encode_len);
383         }
384         if (noti->b_service_responding) {
385                 bundle_encode(noti->b_service_responding,
386                               (bundle_raw **) & b_service_responding, &b_encode_len);
387         }
388         if (noti->b_service_single_launch) {
389                 bundle_encode(noti->b_service_single_launch,
390                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
391         }
392         if (noti->b_service_multi_launch) {
393                 bundle_encode(noti->b_service_multi_launch,
394                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
395         }
396
397         if (noti->b_text) {
398                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
399         }
400         if (noti->b_key) {
401                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
402         }
403         if (noti->b_format_args) {
404                 bundle_encode(noti->b_format_args,
405                               (bundle_raw **) & b_format_args, &b_encode_len);
406         }
407
408         if (noti->b_image_path) {
409                 bundle_encode(noti->b_image_path,
410                               (bundle_raw **) & b_image_path, &b_encode_len);
411         }
412
413         /* Check only simmode property is enable */
414         if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
415                 flag_simmode = 1;
416         }
417
418         /* Make query */
419         *query = sqlite3_mprintf("UPDATE noti_list SET "
420                  "type = %d, "
421                  "layout = %d, "
422                  "launch_pkgname = '%s', "
423                  "image_path = '%s', "
424                  "b_text = '%s', b_key = '%s', tag = $tag, "
425                  "b_format_args = '%s', num_format_args = %d, "
426                  "text_domain = '%s', text_dir = '%s', "
427                  "time = %d, insert_time = %d, "
428                  "args = '%s', group_args = '%s', "
429                  "b_execute_option = '%s', "
430                  "b_service_responding = '%s', "
431                  "b_service_single_launch = '%s', "
432                  "b_service_multi_launch = '%s', "
433                  "sound_type = %d, sound_path = '%s', "
434                  "vibration_type = %d, vibration_path = '%s', "
435                  "led_operation = %d, led_argb = %d, "
436                  "led_on_ms = %d, led_off_ms = %d, "
437                  "flags_for_property = %d, flag_simmode = %d, "
438                  "display_applist = %d, "
439                  "progress_size = $progress_size, progress_percentage = $progress_percentage "
440                  "where priv_id = %d ",
441                  noti->type,
442                  noti->layout,
443                  NOTIFICATION_CHECK_STR(noti->launch_pkgname),
444                  NOTIFICATION_CHECK_STR(b_image_path),
445                  NOTIFICATION_CHECK_STR(b_text), NOTIFICATION_CHECK_STR(b_key),
446                  NOTIFICATION_CHECK_STR(b_format_args), noti->num_format_args,
447                  NOTIFICATION_CHECK_STR(noti->domain),
448                  NOTIFICATION_CHECK_STR(noti->dir),
449                  (int)noti->time, (int)noti->insert_time,
450                  NOTIFICATION_CHECK_STR(args), NOTIFICATION_CHECK_STR(group_args),
451                  NOTIFICATION_CHECK_STR(b_execute_option),
452                  NOTIFICATION_CHECK_STR(b_service_responding),
453                  NOTIFICATION_CHECK_STR(b_service_single_launch),
454                  NOTIFICATION_CHECK_STR(b_service_multi_launch),
455                  noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
456                  noti->vibration_type,
457                  NOTIFICATION_CHECK_STR(noti->vibration_path),
458                  noti->led_operation,
459                  noti->led_argb,
460                  noti->led_on_ms,
461                  noti->led_off_ms,
462                  noti->flags_for_property, flag_simmode, noti->display_applist,
463                  noti->priv_id);
464
465         /* Free decoded data */
466         if (args) {
467                 free(args);
468         }
469         if (group_args) {
470                 free(group_args);
471         }
472
473         if (b_execute_option) {
474                 free(b_execute_option);
475         }
476         if (b_service_responding) {
477                 free(b_service_responding);
478         }
479         if (b_service_single_launch) {
480                 free(b_service_single_launch);
481         }
482         if (b_service_multi_launch) {
483                 free(b_service_multi_launch);
484         }
485
486         if (b_text) {
487                 free(b_text);
488         }
489         if (b_key) {
490                 free(b_key);
491         }
492         if (b_format_args) {
493                 free(b_format_args);
494         }
495
496         if (b_image_path) {
497                 free(b_image_path);
498         }
499
500         if (*query == NULL) {
501                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
502         }
503
504         return NOTIFICATION_ERROR_NONE;
505 }
506
507 static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notification_h noti) {
508         int col = 0;
509
510         if (stmt == NULL || noti == NULL) {
511                 return ;
512         }
513
514         noti->type = sqlite3_column_int(stmt, col++);
515         noti->layout = sqlite3_column_int(stmt, col++);
516         __free_and_set((void **)&(noti->caller_pkgname), notification_db_column_text(stmt, col++));
517         __free_and_set((void **)&(noti->launch_pkgname), notification_db_column_text(stmt, col++));
518         noti->b_image_path = notification_db_column_bundle(stmt, col++);
519         noti->group_id = sqlite3_column_int(stmt, col++);
520         noti->internal_group_id = 0;
521         noti->priv_id = sqlite3_column_int(stmt, col++);
522         __free_and_set((void **)&(noti->tag), notification_db_column_text(stmt, col++));
523
524         noti->b_text = notification_db_column_bundle(stmt, col++);
525         noti->b_key = notification_db_column_bundle(stmt, col++);
526         noti->b_format_args = notification_db_column_bundle(stmt, col++);
527         noti->num_format_args = sqlite3_column_int(stmt, col++);
528
529         __free_and_set((void **)&(noti->domain), notification_db_column_text(stmt, col++));
530         __free_and_set((void **)&(noti->dir), notification_db_column_text(stmt, col++));
531         noti->time = sqlite3_column_int(stmt, col++);
532         noti->insert_time = sqlite3_column_int(stmt, col++);
533         noti->args = notification_db_column_bundle(stmt, col++);
534         noti->group_args = notification_db_column_bundle(stmt, col++);
535
536         noti->b_execute_option = notification_db_column_bundle(stmt, col++);
537         noti->b_service_responding = notification_db_column_bundle(stmt, col++);
538         noti->b_service_single_launch =
539             notification_db_column_bundle(stmt, col++);
540         noti->b_service_multi_launch =
541             notification_db_column_bundle(stmt, col++);
542
543         noti->sound_type = sqlite3_column_int(stmt, col++);
544         __free_and_set((void **)&(noti->sound_path), notification_db_column_text(stmt, col++));
545         noti->vibration_type = sqlite3_column_int(stmt, col++);
546         __free_and_set((void **)&(noti->vibration_path), notification_db_column_text(stmt, col++));
547         noti->led_operation = sqlite3_column_int(stmt, col++);
548         noti->led_argb = sqlite3_column_int(stmt, col++);
549         noti->led_on_ms = sqlite3_column_int(stmt, col++);
550         noti->led_off_ms = sqlite3_column_int(stmt, col++);
551
552         noti->flags_for_property = sqlite3_column_int(stmt, col++);
553         noti->display_applist = sqlite3_column_int(stmt, col++);
554         noti->progress_size = sqlite3_column_double(stmt, col++);
555         noti->progress_percentage = sqlite3_column_double(stmt, col++);
556
557         noti->app_icon_path = NULL;
558         noti->app_name = NULL;
559         noti->temp_title = NULL;
560         noti->temp_content = NULL;
561 }
562
563 static notification_h _notification_noti_get_item(sqlite3_stmt * stmt)
564 {
565         notification_h noti = NULL;
566
567         noti = (notification_h) calloc(1, sizeof(struct _notification));
568         if (noti == NULL) {
569                 return NULL;
570         }
571
572         _notification_noti_populate_from_stmt(stmt, noti);
573
574         return noti;
575 }
576
577 int notification_noti_set_tag(const char *tag, char *value, char *buf, int buf_len)
578 {
579         int len_total = 0;
580
581         len_total += (strlen(tag) * 2) + 5 + strlen(value) + 1;
582
583         if (buf_len <= len_total)
584                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
585
586         snprintf(buf, buf_len, "<%s>%s</%s>", tag, value, tag);
587
588         return NOTIFICATION_ERROR_NONE;
589 }
590
591 char *notification_noti_strip_tag(const char *tagged_str)
592 {
593         if (tagged_str == NULL)
594                 return NULL;
595
596         int len_total = strlen(tagged_str);
597
598         if (len_total == 0)
599                 return NULL;
600
601         char *b_f_e = strstr(tagged_str, ">");
602         char *b_e_s = strstr(tagged_str, "</");
603
604         if (b_f_e == NULL || b_e_s == NULL || (b_e_s - b_f_e - 1) <= 0)
605                 return NULL;
606
607         return strndup(b_f_e + 1, b_e_s - b_f_e - 1);
608 }
609
610 int notification_noti_get_tag_type(const char *tagged_str)
611 {
612         if (tagged_str == NULL)
613                 return TAG_TYPE_INVALID;
614
615         if (strlen(tagged_str)== 0)
616                 return TAG_TYPE_INVALID;
617
618         char *b_f_s = strstr(tagged_str, "<");
619         char *b_f_e = strstr(tagged_str, ">");
620
621         if (b_f_s == NULL || b_f_e == NULL || (b_f_e - b_f_s - 1) <= 0)
622                 return TAG_TYPE_INVALID;
623
624         char *start = b_f_s + 1;
625         int len_tag = b_f_e - b_f_s - 1;
626
627         if (strncmp(start,TAG_TIME,len_tag) == 0) {
628                 return TAG_TYPE_TIME;
629         }
630
631         return TAG_TYPE_INVALID;
632 }
633
634 static int _notification_noti_update_priv_id(sqlite3 * db, int rowid)
635 {
636         int ret = NOTIFICATION_ERROR_NONE;
637         char *query = NULL;
638
639         if (db == NULL) {
640                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
641                 goto err;
642         }
643
644         query = sqlite3_mprintf("UPDATE noti_list SET "
645                         "priv_id = %d, internal_group_id = %d WHERE rowid = %d",
646                         rowid, rowid, rowid);
647         if (query == NULL) {
648                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
649                 goto err;
650         }
651
652         ret = notification_db_exec(db, query, NULL);
653
654 err:
655         if (query) {
656                 sqlite3_free(query);
657         }
658
659         return ret;
660 }
661
662 EXPORT_API int notification_noti_insert(notification_h noti)
663 {
664         int ret = 0;
665         sqlite3 *db = NULL;
666         sqlite3_stmt *stmt = NULL;
667         char *query = NULL;
668         char buf_key[32] = { 0, };
669         const char *title_key = NULL;
670
671         /* Open DB */
672         db = notification_db_open(DBPATH);
673         if (!db) {
674                 return get_last_result();
675         }
676
677         /* Initialize private ID */
678         noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
679         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
680         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
681
682         /* make query */
683         ret = _insertion_query_create(noti, &query);
684         if (ret != NOTIFICATION_ERROR_NONE) {
685                 goto err;
686         }
687
688         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
689         if (ret != SQLITE_OK) {
690                 NOTIFICATION_ERR("Insert Query : %s", query);
691                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
692                                  sqlite3_errmsg(db));
693                 ret = NOTIFICATION_ERROR_FROM_DB;
694                 goto err;
695         }
696
697         /* Get title key */
698         if (noti->b_key != NULL) {
699                 snprintf(buf_key, sizeof(buf_key), "%d",
700                          NOTIFICATION_TEXT_TYPE_TITLE);
701
702                 title_key = bundle_get_val(noti->b_key, buf_key);
703         }
704
705         if (title_key == NULL && noti->b_text != NULL) {
706                 snprintf(buf_key, sizeof(buf_key), "%d",
707                          NOTIFICATION_TEXT_TYPE_TITLE);
708
709                 title_key = bundle_get_val(noti->b_text, buf_key);
710         }
711
712         if (title_key == NULL) {
713                 title_key = noti->caller_pkgname;
714         }
715
716         /* Bind query */
717         ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
718         if (ret != NOTIFICATION_ERROR_NONE) {
719                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
720                 goto err;
721         }
722         ret = _notification_noti_bind_query_text(stmt, "$title_key", title_key);
723         if (ret != NOTIFICATION_ERROR_NONE) {
724                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
725                 goto err;
726         }
727         ret = _notification_noti_bind_query_double(stmt, "$progress_size",noti->progress_size);
728         if (ret != NOTIFICATION_ERROR_NONE) {
729                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
730                 if (stmt) {
731                         sqlite3_finalize(stmt);
732                 }
733                 return ret;
734         }
735         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage",noti->progress_percentage);
736         if (ret != NOTIFICATION_ERROR_NONE) {
737                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
738                 if (stmt) {
739                         sqlite3_finalize(stmt);
740                 }
741                 return ret;
742         }
743
744         ret = sqlite3_step(stmt);
745         if (ret == SQLITE_OK || ret == SQLITE_DONE) {
746                 noti->priv_id = (int)sqlite3_last_insert_rowid(db);
747                 if (_notification_noti_update_priv_id(db, noti->priv_id) == 0) {
748                         ret = NOTIFICATION_ERROR_NONE;
749                 } else {
750                         ret = NOTIFICATION_ERROR_FROM_DB;
751                 }
752         } else {
753                 ret = NOTIFICATION_ERROR_FROM_DB;
754         }
755 err:
756         if (stmt) {
757                 sqlite3_finalize(stmt);
758         }
759
760         /* Close DB */
761         if (db) {
762                 notification_db_close(&db);
763         }
764
765         if (query) {
766                 sqlite3_free(query);
767         }
768
769         return ret;
770 }
771
772 int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id)
773 {
774         int ret = 0;
775         char *query = NULL;
776         sqlite3 *db = NULL;
777         sqlite3_stmt *stmt = NULL;
778
779         if (priv_id < 0 || noti == NULL) {
780                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
781                 goto err;
782         }
783
784         /* Open DB */
785         db = notification_db_open(DBPATH);
786         if (!db) {
787                 return get_last_result();
788         }
789
790         char *base_query = "select "
791                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
792                          "tag, b_text, b_key, b_format_args, num_format_args, "
793                          "text_domain, text_dir, time, insert_time, args, group_args, "
794                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
795                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
796                          "flags_for_property, display_applist, progress_size, progress_percentage "
797                          "from noti_list ";
798
799         if (pkgname != NULL) {
800                 query = sqlite3_mprintf("%s where caller_pkgname = '%s' and priv_id = %d",
801                                 base_query ,pkgname, priv_id);
802         } else {
803                 query = sqlite3_mprintf("%s where priv_id = %d", base_query,  priv_id);
804         }
805         if (query == NULL) {
806                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
807                 goto err;
808         }
809
810         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
811         if (ret != SQLITE_OK) {
812                 NOTIFICATION_ERR("select Query : %s", query);
813                 NOTIFICATION_ERR("select DB error(%d) : %s", ret,
814                                  sqlite3_errmsg(db));
815                 ret = NOTIFICATION_ERROR_FROM_DB;
816                 goto err;
817         }
818
819         ret = sqlite3_step(stmt);
820         if (ret == SQLITE_ROW) {
821                 _notification_noti_populate_from_stmt(stmt, noti);
822                 ret = NOTIFICATION_ERROR_NONE;
823         } else {
824                 ret = NOTIFICATION_ERROR_FROM_DB;
825         }
826 err:
827         if (query) {
828                 sqlite3_free(query);
829         }
830
831         if (stmt) {
832                 sqlite3_finalize(stmt);
833         }
834
835         /* Close DB */
836         if (db != NULL) {
837                 notification_db_close(&db);
838         }
839
840         return ret;
841 }
842
843 EXPORT_API int notification_noti_get_by_tag(notification_h noti, char *pkgname, char* tag)
844 {
845         int ret = 0;
846         char *query = NULL;
847         sqlite3 *db = NULL;
848         sqlite3_stmt *stmt = NULL;
849
850         if (tag == NULL || noti == NULL) {
851                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
852                 goto err;
853         }
854
855         /* Open DB */
856         db = notification_db_open(DBPATH);
857         if (!db) {
858                 return get_last_result();
859         }
860
861         if (pkgname != NULL) {
862                 ret = sqlite3_prepare_v2(db, "select "
863                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
864                          "tag, b_text, b_key, b_format_args, num_format_args, "
865                          "text_domain, text_dir, time, insert_time, args, group_args, "
866                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
867                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
868                          "flags_for_property, display_applist, progress_size, progress_percentage "
869                          "from noti_list where caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
870                 if (ret != SQLITE_OK) {
871                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
872                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
873                 }
874
875                 ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
876                 if (ret != SQLITE_OK) {
877                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
878                         goto err;
879                 }
880
881                 ret = sqlite3_bind_text(stmt, 2,  tag, -1, SQLITE_TRANSIENT);
882                 if (ret != SQLITE_OK) {
883                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
884                         goto err;
885                 } 
886         } else {
887                 ret = sqlite3_prepare_v2(db, "select "
888                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
889                          "tag, b_text, b_key, b_format_args, num_format_args, "
890                          "text_domain, text_dir, time, insert_time, args, group_args, "
891                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
892                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
893                          "flags_for_property, display_applist, progress_size, progress_percentage "
894                          "from noti_list where  tag = ?", -1, &stmt, NULL);
895                 if (ret != SQLITE_OK) {
896                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
897                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
898                 }
899
900                 ret = sqlite3_bind_text(stmt, 1, tag, -1, SQLITE_TRANSIENT);
901                 if (ret != SQLITE_OK) {
902                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
903                         goto err;
904                 }
905         }
906 /*
907         char *base_query = "select "
908                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
909                          "tag, b_text, b_key, b_format_args, num_format_args, "
910                          "text_domain, text_dir, time, insert_time, args, group_args, "
911                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
912                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
913                          "flags_for_property, display_applist, progress_size, progress_percentage "
914                          "from noti_list ";
915
916         if (pkgname != NULL) {
917                 query = sqlite3_mprintf("%s where caller_pkgname = '%s' and tag = '%s'",
918                                 base_query ,pkgname, tag);
919         } else {
920                 query = sqlite3_mprintf("%s where tag = '%s'", base_query,  tag);
921         }
922         if (query == NULL) {
923                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
924                 goto err;
925         }
926
927         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
928         if (ret != SQLITE_OK) {
929                 NOTIFICATION_ERR("select Query : %s", query);
930                 NOTIFICATION_ERR("select DB error(%d) : %s", ret,
931                                  sqlite3_errmsg(db));
932                 ret = NOTIFICATION_ERROR_FROM_DB;
933                 goto err;
934         }
935 */
936         ret = sqlite3_step(stmt);
937         if (ret == SQLITE_ROW) {
938                 _notification_noti_populate_from_stmt(stmt, noti);
939                 ret = NOTIFICATION_ERROR_NONE;
940         } else {
941                 ret = NOTIFICATION_ERROR_FROM_DB;
942         }
943 err:
944         if (query) {
945                 sqlite3_free(query);
946         }
947
948         if (stmt) {
949                 sqlite3_finalize(stmt);
950         }
951
952         /* Close DB */
953         if (db != NULL) {
954                 notification_db_close(&db);
955         }
956
957         return ret;
958 }
959
960 EXPORT_API int notification_noti_update(notification_h noti)
961 {
962         int ret = 0;
963         sqlite3 *db;
964         sqlite3_stmt *stmt = NULL;
965         char *query = NULL;
966
967         /* Open DB */
968         db = notification_db_open(DBPATH);
969         if (!db) {
970                 return get_last_result();
971         }
972
973         /* Check private ID is exist */
974         ret = _notification_noti_check_priv_id(noti, db);
975         if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
976                 ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
977                 goto err;
978         }
979
980         /* make update query */
981         ret = _update_query_create(noti, &query);
982         if (ret != NOTIFICATION_ERROR_NONE) {
983                 goto err;
984         }
985
986         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
987         if (ret != SQLITE_OK) {
988                 NOTIFICATION_ERR("Insert Query : %s", query);
989                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
990                                  sqlite3_errmsg(db));
991                 ret = NOTIFICATION_ERROR_FROM_DB;
992                 goto err;
993         }
994
995         ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
996         if (ret != NOTIFICATION_ERROR_NONE) {
997                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
998                 goto err;
999         }
1000         ret = _notification_noti_bind_query_double(stmt, "$progress_size",noti->progress_size);
1001         if (ret != NOTIFICATION_ERROR_NONE) {
1002                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
1003                 goto err;
1004         }
1005         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage",noti->progress_percentage);
1006         if (ret != NOTIFICATION_ERROR_NONE) {
1007                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
1008                 goto err;
1009         }
1010
1011         ret = sqlite3_step(stmt);
1012         if (ret == SQLITE_OK || ret == SQLITE_DONE) {
1013                 ret = NOTIFICATION_ERROR_NONE;
1014         } else {
1015                 ret = NOTIFICATION_ERROR_FROM_DB;
1016         }
1017 err:
1018         if (stmt) {
1019                 sqlite3_finalize(stmt);
1020         }
1021
1022         /* Close DB */
1023         if (db) {
1024                 notification_db_close(&db);
1025         }
1026
1027         if (query) {
1028                 sqlite3_free(query);
1029         }
1030
1031         return ret;
1032 }
1033
1034 EXPORT_API int notification_noti_delete_all(notification_type_e type, const char *pkgname, int *num_deleted, int **list_deleted_rowid)
1035 {
1036         int ret = NOTIFICATION_ERROR_NONE;
1037         int ret_tmp = NOTIFICATION_ERROR_NONE;
1038         int i = 0, data_cnt = 0;
1039         sqlite3 *db = NULL;
1040         sqlite3_stmt *stmt = NULL;
1041         char buf[128] = { 0, };
1042         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1043         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1044         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1045
1046         /* Open DB */
1047         db = notification_db_open(DBPATH);
1048         if (!db) {
1049                 return get_last_result();
1050         }
1051
1052         if (pkgname == NULL) {
1053                 if (type != NOTIFICATION_TYPE_NONE) {
1054                         snprintf(query_where, sizeof(query_where),
1055                                  "where type = %d ", type);
1056                 }
1057         } else {
1058                 if (type == NOTIFICATION_TYPE_NONE) {
1059                         snprintf(query_where, sizeof(query_where),
1060                                  "where caller_pkgname = '%s' ", pkgname);
1061                 } else {
1062                         snprintf(query_where, sizeof(query_where),
1063                                  "where caller_pkgname = '%s' and type = %d ",
1064                                  pkgname, type);
1065                 }
1066         }
1067
1068         if (num_deleted != NULL) {
1069                 *num_deleted = 0;
1070         }
1071         if (list_deleted_rowid != NULL) {
1072                 *list_deleted_rowid = NULL;
1073                 snprintf(query, sizeof(query),
1074                                 "select priv_id from noti_list %s ", query_where);
1075
1076                 ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1077                 if (ret != SQLITE_OK) {
1078                         NOTIFICATION_ERR("Select Query : %s", query);
1079                         NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1080                                          sqlite3_errmsg(db));
1081
1082                         ret = NOTIFICATION_ERROR_FROM_DB;
1083                         goto err;
1084                 }
1085
1086                 while(sqlite3_step(stmt) == SQLITE_ROW) {
1087                         if (data_cnt % 8 == 0) {
1088                                 int *tmp;
1089
1090                                 tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
1091                                 if (tmp) {
1092                                         *list_deleted_rowid = tmp;
1093                                 } else {
1094                                         NOTIFICATION_ERR("Heap: %s\n", strerror(errno));
1095                                         /*!
1096                                          * \TODO
1097                                          * How can I handle this?
1098                                          */
1099                                         free(*list_deleted_rowid);
1100                                         *list_deleted_rowid = NULL;
1101                                         ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1102                                         goto err;
1103                                 }
1104                         }
1105                         *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
1106                         data_cnt++;
1107                 }
1108
1109                 if (stmt) {
1110                         sqlite3_finalize(stmt);
1111                         stmt = NULL;
1112                 }
1113
1114                 if (data_cnt > 0) {
1115                         query_where[0] = '\0';
1116                         snprintf(query_base, sizeof(query_base) - 1, "delete from noti_list");
1117                         for (i = 0; i < data_cnt ; i++) {
1118                                 if (i % NOTI_BURST_DELETE_UNIT == 0 && i != 0) {
1119                                         snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1120                                         ret_tmp = notification_db_exec(db, query, NULL);
1121                                         query_where[0] = '\0';
1122                                         if (ret == NOTIFICATION_ERROR_NONE) {
1123                                                 ret = ret_tmp;
1124                                         }
1125                                 }
1126                                 snprintf(buf, sizeof(buf) - 1, "%s%d", (i % NOTI_BURST_DELETE_UNIT == 0) ? "" : ",", *((*list_deleted_rowid) + i));
1127                                 strncat(query_where, buf,sizeof(query_where) - strlen(query_where) - 1);
1128                         }
1129                         if ((i <= NOTI_BURST_DELETE_UNIT) || ((i % NOTI_BURST_DELETE_UNIT) > 0) ) {
1130                                 snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1131                                 ret_tmp = notification_db_exec(db, query, NULL);
1132                                 if (ret == NOTIFICATION_ERROR_NONE) {
1133                                         ret = ret_tmp;
1134                                 }
1135                         }
1136                 } else {
1137                         free(*list_deleted_rowid);
1138                         *list_deleted_rowid = NULL;
1139                 }
1140
1141                 if (num_deleted != NULL) {
1142                         *num_deleted = data_cnt;
1143                 }
1144         } else {
1145                 /* Make main query */
1146                 snprintf(query_base, sizeof(query_base), "delete from noti_list ");
1147                 snprintf(query, sizeof(query), "%s %s", query_base, query_where);
1148
1149                 ret = notification_db_exec(db, query, NULL);
1150
1151                 if (num_deleted != NULL) {
1152                         *num_deleted = sqlite3_changes(db);
1153                 }
1154         }
1155
1156 err:
1157         if (stmt) {
1158                 sqlite3_finalize(stmt);
1159         }
1160         /* Close DB */
1161         if (db) {
1162                 notification_db_close(&db);
1163         }
1164
1165         return ret;
1166 }
1167
1168 int notification_noti_delete_group_by_group_id(const char *pkgname,
1169                                                int group_id, int *num_deleted, int **list_deleted_rowid)
1170 {
1171         int ret = NOTIFICATION_ERROR_NONE;
1172         int ret_tmp = NOTIFICATION_ERROR_NONE;
1173         sqlite3 *db = NULL;
1174         int i = 0, data_cnt = 0;
1175         sqlite3_stmt *stmt = NULL;
1176         char buf[128] = { 0, };
1177         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1178         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1179         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1180
1181         /* Check pkgname is valid */
1182         if (pkgname == NULL) {
1183                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1184         }
1185
1186         snprintf(query_where, sizeof(query_where),
1187                         "where caller_pkgname = '%s' and group_id = %d", pkgname, group_id);
1188
1189         /* Open DB */
1190         db = notification_db_open(DBPATH);
1191         if (!db) {
1192                 return get_last_result();
1193         }
1194
1195         if (num_deleted != NULL) {
1196                 *num_deleted = 0;
1197         }
1198         if (list_deleted_rowid != NULL) {
1199                 *list_deleted_rowid = NULL;
1200                 snprintf(query, sizeof(query),
1201                                 "select priv_id from noti_list %s ", query_where);
1202
1203                 ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1204                 if (ret != SQLITE_OK) {
1205                         NOTIFICATION_ERR("Select Query : %s", query);
1206                         NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1207                                          sqlite3_errmsg(db));
1208
1209                         ret = NOTIFICATION_ERROR_FROM_DB;
1210                         goto err;
1211                 }
1212
1213                 while(sqlite3_step(stmt) == SQLITE_ROW) {
1214                         if (data_cnt % 8 == 0) {
1215                                 int *tmp;
1216                                 tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
1217                                 if (tmp) {
1218                                         *list_deleted_rowid = tmp;
1219                                 } else {
1220                                         free(*list_deleted_rowid);
1221                                         *list_deleted_rowid = NULL;
1222                                         ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1223                                         goto err;
1224                                 }
1225                         }
1226                         *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
1227                         data_cnt++;
1228                 }
1229
1230                 if (stmt) {
1231                         sqlite3_finalize(stmt);
1232                         stmt = NULL;
1233                 }
1234
1235                 if (data_cnt > 0) {
1236                         query_where[0] = '\0';
1237                         snprintf(query_base, sizeof(query_base) - 1, "delete from noti_list");
1238                         for (i = 0; i < data_cnt ; i++) {
1239                                 if (i % NOTI_BURST_DELETE_UNIT == 0 && i != 0) {
1240                                         snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1241                                         ret_tmp = notification_db_exec(db, query, NULL);
1242                                         query_where[0] = '\0';
1243                                         if (ret == NOTIFICATION_ERROR_NONE) {
1244                                                 ret = ret_tmp;
1245                                         }
1246                                 }
1247                                 snprintf(buf, sizeof(buf) - 1, "%s%d", (i % NOTI_BURST_DELETE_UNIT == 0) ? "" : ",", *((*list_deleted_rowid) + i));
1248                                 strncat(query_where, buf,sizeof(query_where) - strlen(query_where) - 1);
1249                         }
1250                         if ((i <= NOTI_BURST_DELETE_UNIT) || ((i % NOTI_BURST_DELETE_UNIT) > 0) ) {
1251                                 snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1252                                 ret_tmp = notification_db_exec(db, query, NULL);
1253                                 if (ret == NOTIFICATION_ERROR_NONE) {
1254                                         ret = ret_tmp;
1255                                 }
1256                         }
1257                 } else {
1258                         free(*list_deleted_rowid);
1259                         *list_deleted_rowid = NULL;
1260                 }
1261
1262                 if (num_deleted != NULL) {
1263                         *num_deleted = data_cnt;
1264                 }
1265         } else {
1266                 /* Make query */
1267                 snprintf(query, sizeof(query), "delete from noti_list %s", query_where);
1268
1269                 /* execute DB */
1270                 ret = notification_db_exec(db, query, NULL);
1271         }
1272
1273 err:
1274         if (stmt) {
1275                 sqlite3_finalize(stmt);
1276         }
1277         /* Close DB */
1278         if (db) {
1279                 notification_db_close(&db);
1280         }
1281
1282         return ret;
1283 }
1284
1285 int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
1286 {
1287         sqlite3 *db = NULL;
1288         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1289         int internal_group_id = 0;
1290         int ret;
1291
1292         /* Check pkgname is valid */
1293         if (pkgname == NULL) {
1294                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1295         }
1296
1297         /* Open DB */
1298         db = notification_db_open(DBPATH);
1299         if (!db) {
1300                 return get_last_result();
1301         }
1302
1303         /* Get internal group id using priv id */
1304         internal_group_id =
1305             _notification_noti_get_internal_group_id_by_priv_id(pkgname,
1306                                                                 priv_id, db);
1307
1308         /* Make query */
1309         snprintf(query, sizeof(query), "delete from noti_list "
1310                  "where caller_pkgname = '%s' and internal_group_id = %d",
1311                  pkgname, internal_group_id);
1312
1313         /* execute DB */
1314         ret = notification_db_exec(db, query, NULL);
1315
1316         /* Close DB */
1317         notification_db_close(&db);
1318
1319         return ret;
1320 }
1321
1322 EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
1323 {
1324         sqlite3 *db = NULL;
1325         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1326         int ret;
1327
1328         /* Check pkgname is valid */
1329         if (pkgname == NULL) {
1330                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1331         }
1332
1333         /* Open DB */
1334         db = notification_db_open(DBPATH);
1335         if (!db) {
1336                 return get_last_result();
1337         }
1338
1339         /* Make query */
1340         snprintf(query, sizeof(query), "delete from noti_list "
1341                  "where caller_pkgname = '%s' and priv_id = %d", pkgname,
1342                  priv_id);
1343
1344         /* execute DB */
1345         ret = notification_db_exec(db, query, NULL);
1346
1347         /* Close DB */
1348         if (db) {
1349                 notification_db_close(&db);
1350         }
1351
1352         return ret;
1353 }
1354
1355 EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgname, int priv_id, int *num_changes)
1356 {
1357         sqlite3 *db = NULL;
1358         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1359         int ret;
1360
1361         /* Check pkgname is valid */
1362         if (pkgname == NULL) {
1363                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1364         }
1365
1366         /* Open DB */
1367         db = notification_db_open(DBPATH);
1368         if (!db) {
1369                 return get_last_result();
1370         }
1371
1372         /* Make query */
1373         snprintf(query, sizeof(query), "delete from noti_list "
1374                  "where caller_pkgname = '%s' and priv_id = %d", pkgname,
1375                  priv_id);
1376
1377         /* execute DB */
1378         ret = notification_db_exec(db, query, num_changes);
1379
1380         if (num_changes != NULL) {
1381                 NOTIFICATION_DBG("deleted num:%d", *num_changes);
1382         }
1383
1384         /* Close DB */
1385         if (db) {
1386                 notification_db_close(&db);
1387         }
1388
1389         return ret;
1390 }
1391
1392 int notification_noti_get_count(notification_type_e type,
1393                                                  const char *pkgname,
1394                                                  int group_id, int priv_id,
1395                                                  int *count)
1396 {
1397         sqlite3 *db = NULL;
1398         sqlite3_stmt *stmt = NULL;
1399         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1400         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1401         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1402         char query_where_more[NOTIFICATION_QUERY_MAX] = { 0, };
1403
1404         int ret = 0, get_count = 0, internal_group_id = 0;
1405         int status = VCONFKEY_TELEPHONY_SIM_UNKNOWN;
1406         int flag_where = 0;
1407         int flag_where_more = 0;
1408         int ret_vconf = 0;
1409
1410         /* Open DB */
1411         db = notification_db_open(DBPATH);
1412         if (!db) {
1413                 return get_last_result();
1414         }
1415
1416         /* Check current sim status */
1417         ret_vconf = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1418
1419         /* Make query */
1420         snprintf(query_base, sizeof(query_base),
1421                  "select count(*) from noti_list ");
1422
1423         if (pkgname != NULL) {
1424                 if (group_id == NOTIFICATION_GROUP_ID_NONE) {
1425                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1426                                 snprintf(query_where, sizeof(query_where),
1427                                          "where caller_pkgname = '%s' ",
1428                                          pkgname);
1429                                 flag_where = 1;
1430                         } else {
1431                                 internal_group_id =
1432                                     _notification_noti_get_internal_group_id_by_priv_id
1433                                     (pkgname, priv_id, db);
1434                                 snprintf(query_where, sizeof(query_where),
1435                                          "where caller_pkgname = '%s' and internal_group_id = %d ",
1436                                          pkgname, internal_group_id);
1437                                 flag_where = 1;
1438                         }
1439                 } else {
1440                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1441                                 snprintf(query_where, sizeof(query_where),
1442                                          "where caller_pkgname = '%s' and group_id = %d ",
1443                                          pkgname, group_id);
1444                                 flag_where = 1;
1445                         } else {
1446                                 internal_group_id =
1447                                     _notification_noti_get_internal_group_id_by_priv_id
1448                                     (pkgname, priv_id, db);
1449                                 snprintf(query_where, sizeof(query_where),
1450                                          "where caller_pkgname = '%s' and internal_group_id = %d ",
1451                                          pkgname, internal_group_id);
1452                                 flag_where = 1;
1453                         }
1454                 }
1455
1456         }
1457
1458         if (ret_vconf == 0 && status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1459                 if (type != NOTIFICATION_TYPE_NONE) {
1460                         snprintf(query_where_more, sizeof(query_where_more),
1461                                  "type = %d ", type);
1462                         flag_where_more = 1;
1463                 }
1464         } else {
1465                 if (type != NOTIFICATION_TYPE_NONE) {
1466                         snprintf(query_where_more, sizeof(query_where_more),
1467                                  "type = %d and flag_simmode = 0 ", type);
1468                         flag_where_more = 1;
1469                 } else {
1470                         snprintf(query_where_more, sizeof(query_where_more),
1471                                  "flag_simmode = 0 ");
1472                         flag_where_more = 1;
1473                 }
1474         }
1475
1476         if (flag_where == 1) {
1477                 if (flag_where_more == 1) {
1478                         snprintf(query, sizeof(query), "%s %s and %s",
1479                                  query_base, query_where, query_where_more);
1480                 } else {
1481                         snprintf(query, sizeof(query), "%s %s", query_base,
1482                                  query_where);
1483                 }
1484
1485         } else {
1486                 if (flag_where_more == 1) {
1487                         snprintf(query, sizeof(query), "%s where %s",
1488                                  query_base, query_where_more);
1489                 } else {
1490                         snprintf(query, sizeof(query), "%s", query_base);
1491                 }
1492         }
1493
1494         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1495         if (ret != SQLITE_OK) {
1496                 NOTIFICATION_ERR("Select Query : %s", query);
1497                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1498                                  sqlite3_errmsg(db));
1499
1500                 ret = NOTIFICATION_ERROR_FROM_DB;
1501                 goto err;
1502         }
1503
1504         ret = sqlite3_step(stmt);
1505         if (ret == SQLITE_ROW) {
1506                 get_count = sqlite3_column_int(stmt, 0);
1507         }
1508
1509         ret = NOTIFICATION_ERROR_NONE;
1510
1511 err:
1512         if (stmt) {
1513                 sqlite3_finalize(stmt);
1514         }
1515
1516         /* Close DB */
1517         if (db) {
1518                 notification_db_close(&db);
1519         }
1520
1521         *count = get_count;
1522
1523         return ret;
1524 }
1525
1526 int notification_noti_get_grouping_list(notification_type_e type,
1527                                                          int count,
1528                                                          notification_list_h *
1529                                                          list)
1530 {
1531         sqlite3 *db = NULL;
1532         sqlite3_stmt *stmt = NULL;
1533         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1534         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1535         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1536
1537         int ret = 0;
1538         notification_list_h get_list = NULL;
1539         notification_h noti = NULL;
1540         int internal_count = 0;
1541         int status;
1542
1543         /* Open DB */
1544         db = notification_db_open(DBPATH);
1545         if (!db) {
1546                 return get_last_result();
1547         }
1548
1549         /* Check current sim status */
1550         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1551
1552         /* Make query */
1553         snprintf(query_base, sizeof(query_base), "select "
1554                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1555                  "tag, b_text, b_key, b_format_args, num_format_args, "
1556                  "text_domain, text_dir, time, insert_time, args, group_args, "
1557                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1558                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1559                  "flags_for_property, display_applist, progress_size, progress_percentage "
1560                  "from noti_list ");
1561
1562         if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1563                 if (type != NOTIFICATION_TYPE_NONE) {
1564                         snprintf(query_where, sizeof(query_where),
1565                                  "where type = %d ", type);
1566                 }
1567         } else {
1568                 if (type != NOTIFICATION_TYPE_NONE) {
1569                         snprintf(query_where, sizeof(query_where),
1570                                  "where type = %d and flag_simmode = 0 ", type);
1571                 } else {
1572                         snprintf(query_where, sizeof(query_where),
1573                                  "where flag_simmode = 0 ");
1574                 }
1575         }
1576
1577         snprintf(query, sizeof(query),
1578                  "%s %s "
1579                  "group by internal_group_id "
1580                  "order by rowid desc, time desc", query_base, query_where);
1581
1582         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1583         if (ret != SQLITE_OK) {
1584                 NOTIFICATION_ERR("Select Query : %s", query);
1585                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1586                                  sqlite3_errmsg(db));
1587
1588                 ret = NOTIFICATION_ERROR_FROM_DB;
1589                 goto err;
1590         }
1591
1592         while (sqlite3_step(stmt) == SQLITE_ROW) {
1593                 /* Make notification list */
1594                 noti = _notification_noti_get_item(stmt);
1595                 if (noti != NULL) {
1596                         internal_count++;
1597
1598                         get_list = notification_list_append(get_list, noti);
1599
1600                         if (count != -1 && internal_count >= count) {
1601                                 NOTIFICATION_INFO
1602                                     ("internal count %d >= count %d",
1603                                      internal_count, count);
1604                                 break;
1605                         }
1606                 }
1607         }
1608
1609         ret = NOTIFICATION_ERROR_NONE;
1610
1611 err:
1612         if (stmt) {
1613                 sqlite3_finalize(stmt);
1614         }
1615
1616         /* Close DB */
1617         if (db) {
1618                 notification_db_close(&db);
1619         }
1620
1621         if (get_list != NULL) {
1622                 *list = notification_list_get_head(get_list);
1623         }
1624
1625         return ret;
1626 }
1627
1628 int notification_noti_get_detail_list(const char *pkgname,
1629                                                        int group_id,
1630                                                        int priv_id, int count,
1631                                                        notification_list_h *list)
1632 {
1633         sqlite3 *db = NULL;
1634         sqlite3_stmt *stmt = NULL;
1635         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1636         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1637
1638         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1639         int ret = 0;
1640         notification_list_h get_list = NULL;
1641         notification_h noti = NULL;
1642         int internal_count = 0;
1643         int internal_group_id = 0;
1644         int status = 0; /* If the vconf_get_int failed, the status will be the garbage value */
1645
1646         /* Open DB */
1647         db = notification_db_open(DBPATH);
1648         if (!db) {
1649                 return get_last_result();
1650         }
1651
1652         /* Check current sim status */
1653         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1654
1655         /* Make query */
1656         snprintf(query_base, sizeof(query_base), "select "
1657                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1658                  "tag, b_text, b_key, b_format_args, num_format_args, "
1659                  "text_domain, text_dir, time, insert_time, args, group_args, "
1660                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1661                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1662                  "flags_for_property, display_applist, progress_size, progress_percentage "
1663                  "from noti_list ");
1664
1665         if (priv_id == NOTIFICATION_PRIV_ID_NONE && group_id == NOTIFICATION_GROUP_ID_NONE) {
1666                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1667                         snprintf(query_where, sizeof(query_where),
1668                                  "where  caller_pkgname = '%s' ", pkgname);
1669                 } else {
1670                         snprintf(query_where, sizeof(query_where),
1671                                  "where  caller_pkgname = '%s' and flag_simmode = 0 ", pkgname);
1672                 }
1673         } else {
1674                 internal_group_id =
1675                     _notification_noti_get_internal_group_id_by_priv_id(pkgname,
1676                                                                         priv_id, db);
1677
1678                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1679                         snprintf(query_where, sizeof(query_where),
1680                                  "where  caller_pkgname = '%s' and internal_group_id = %d ",
1681                                  pkgname, internal_group_id);
1682                 } else {
1683                         snprintf(query_where, sizeof(query_where),
1684                                  "where  caller_pkgname = '%s' and internal_group_id = %d and flag_simmode = 0 ",
1685                                  pkgname, internal_group_id);
1686                 }
1687         }
1688
1689         snprintf(query, sizeof(query),
1690                  "%s %s "
1691                  "order by rowid desc, time desc", query_base, query_where);
1692
1693         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1694         if (ret != SQLITE_OK) {
1695                 NOTIFICATION_ERR("Select Query : %s", query);
1696                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1697                                  sqlite3_errmsg(db));
1698
1699                 ret = NOTIFICATION_ERROR_FROM_DB;
1700                 goto err;
1701         }
1702
1703         while (sqlite3_step(stmt) == SQLITE_ROW) {
1704                 /* Make notification list */
1705                 noti = _notification_noti_get_item(stmt);
1706                 if (noti != NULL) {
1707                         internal_count++;
1708
1709                         get_list = notification_list_append(get_list, noti);
1710
1711                         if (count != -1 && internal_count >= count) {
1712                                 NOTIFICATION_INFO
1713                                     ("internal count %d >= count %d",
1714                                      internal_count, count);
1715                                 break;
1716                         }
1717                 }
1718         }
1719
1720         ret = NOTIFICATION_ERROR_NONE;
1721
1722 err:
1723         if (stmt) {
1724                 sqlite3_finalize(stmt);
1725         }
1726
1727         /* Close DB */
1728         if (db) {
1729                 notification_db_close(&db);
1730         }
1731
1732         if (get_list != NULL) {
1733                 *list = notification_list_get_head(get_list);
1734         }
1735
1736         return ret;
1737 }
1738
1739 EXPORT_API int notification_noti_check_tag(notification_h noti)
1740 {
1741         int result = 0;
1742         int ret = NOTIFICATION_ERROR_NONE;
1743         char *query = NULL;
1744         sqlite3 *db;
1745         sqlite3_stmt *stmt = NULL;
1746
1747         if (noti->tag == NULL) {
1748                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
1749         }
1750
1751         /* Open DB */
1752         db = notification_db_open(DBPATH);
1753         if (!db) {
1754                 return get_last_result();
1755         }
1756
1757         ret = sqlite3_prepare_v2(db, "SELECT priv_id FROM noti_list WHERE caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
1758         if (ret != SQLITE_OK) {
1759                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1760                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1761         }
1762
1763         ret = sqlite3_bind_text(stmt, 1, noti->caller_pkgname, -1, SQLITE_TRANSIENT);
1764         if (ret != SQLITE_OK) {
1765                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1766                 goto err;
1767         }
1768
1769         ret = sqlite3_bind_text(stmt, 2, noti->tag, -1, SQLITE_TRANSIENT);
1770         if (ret != SQLITE_OK) {
1771                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1772                 goto err;
1773         }
1774
1775 /*
1776         query = sqlite3_mprintf("select priv_id from noti_list where caller_pkgname = '%s' and tag = '%s'",
1777                  noti->caller_pkgname, noti->tag);
1778         if (query == NULL) {
1779                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1780                 goto err;
1781         }
1782
1783         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1784         if (ret != SQLITE_OK) {
1785                 NOTIFICATION_ERR("Get priv id DB err(%d) : %s", ret,
1786                                  sqlite3_errmsg(db));
1787                 ret = NOTIFICATION_ERROR_FROM_DB;
1788                 goto err;
1789         }
1790 */
1791         ret = sqlite3_step(stmt);
1792         if (ret == SQLITE_ROW) {
1793                 result = sqlite3_column_int(stmt, 0);
1794         } else {
1795                 result = 0;
1796         }
1797
1798         sqlite3_finalize(stmt);
1799
1800         /* If result > 0, there is priv_id in DB */
1801         if (result > 0) {
1802                 noti->priv_id = result;
1803                 ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
1804         } else {
1805                 ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
1806         }
1807
1808 err:
1809         if (query) {
1810                 sqlite3_free(query);
1811         }
1812
1813         return ret;
1814 }
1815
1816 static void popup_timeout_cb(void *data, Evas_Object *obj, void *event_info)
1817 {
1818         Eina_List *list = NULL;
1819         char *msg = NULL;
1820         int count = 0;
1821
1822         evas_object_del(toast_popup);
1823         toast_popup = NULL;
1824         evas_object_del((Evas_Object *)data);
1825
1826         count = eina_list_count(toast_list);
1827
1828         if (count == 1){
1829                 msg = (char *)eina_list_data_get(toast_list);
1830                 free(msg);
1831
1832                 eina_list_free(toast_list);
1833                 toast_list = NULL;
1834         } else if (count > 1) {
1835                 msg = (char *)eina_list_data_get(toast_list);
1836                 toast_list = eina_list_remove(toast_list, msg);
1837                 free(msg);
1838                 _post_toast_message((char *)eina_list_data_get(toast_list));
1839         }
1840 }
1841
1842 int _post_toast_message(char *message)
1843 {
1844         int let = 0;
1845         Evas_Object *toast_window;
1846         Evas *e;
1847         Ecore_Evas *ee;
1848         double scale = elm_config_scale_get();
1849
1850
1851         toast_window = elm_win_add(NULL, "toast", ELM_WIN_BASIC);
1852
1853         elm_win_alpha_set(toast_window, EINA_TRUE);
1854         elm_win_title_set(toast_window, "toast");
1855
1856         elm_win_indicator_mode_set(toast_window, ELM_WIN_INDICATOR_SHOW);
1857         elm_win_indicator_type_set(toast_window,ELM_WIN_INDICATOR_TYPE_1);
1858
1859         //elm_win_autodel_set(toast_win, EINA_TRUE);
1860         if (elm_win_wm_rotation_supported_get(toast_window)) {
1861                 int rots[4] = { 0, 90, 180, 270 };
1862                 elm_win_wm_rotation_available_rotations_set(toast_window, (const int*)(&rots), 4);
1863         }
1864
1865         e = evas_object_evas_get(toast_window);
1866         ee = ecore_evas_ecore_evas_get(e);
1867         ecore_evas_name_class_set(ee, "TOAST_POPUP", "SYSTEM_POPUP");
1868
1869         evas_object_resize(toast_window, (480 * scale), (650 * scale));
1870         ecore_x_window_shape_input_rectangle_set(elm_win_xwindow_get(toast_window), 0, 0, (480 * scale), (650 * scale));
1871
1872         toast_popup = elm_popup_add(toast_window);
1873
1874         elm_object_style_set(toast_popup, "toast");
1875         evas_object_size_hint_weight_set(toast_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1876
1877         elm_object_text_set(toast_popup,message);
1878
1879         if (eina_list_count(toast_list) != 1) {
1880                 elm_popup_timeout_set(toast_popup, 1.0);
1881         }
1882         else {
1883                 elm_popup_timeout_set(toast_popup, 3.0);
1884         }
1885         evas_object_smart_callback_add(toast_popup, "timeout", popup_timeout_cb, (void *)toast_window);
1886
1887         elm_win_prop_focus_skip_set(toast_window, EINA_TRUE);
1888
1889         evas_object_show(toast_window);
1890         evas_object_show(toast_popup);
1891
1892         return 0;
1893 }
1894
1895 EXPORT_API int notification_noti_post_toast_message(const char *message)
1896 {
1897         int let = 0;
1898         char *msg = NULL;
1899         int count = 0;
1900
1901         msg = (char *)calloc(strlen(message) + 1, sizeof(char));
1902         strcpy(msg, message);
1903
1904 /*
1905         if (eina_list_count(toast_list) == 10) {
1906                 toast_list = eina_list_last(toast_list);
1907                 eina_list_data_set(toast_list, msg);
1908                 toast_list = eina_list_nth_list(toast_list, 0);
1909         }
1910         else {
1911 */
1912
1913         count = eina_list_count(toast_list);
1914         if (count == 0) {
1915                 toast_list = eina_list_append(toast_list, msg);
1916                 let = _post_toast_message(msg);
1917         }
1918         else if (count == 1) {
1919                 if (strcmp(msg, (char *)eina_list_nth(toast_list, count - 1)) == 0) {
1920                         elm_popup_timeout_set(toast_popup, 3.0);
1921                 }
1922                 else {
1923                         toast_list = eina_list_append(toast_list, msg);
1924                         elm_popup_timeout_set(toast_popup, 1.0);
1925                 }
1926         }
1927         else if (count >= 2) {
1928                 if (strcmp(msg, (char *)eina_list_nth(toast_list, count - 1)) == 0) {
1929                         free(msg);
1930                         return 0;
1931                 }
1932                 else {
1933                         toast_list = eina_list_append(toast_list, msg);
1934                 }
1935         }
1936
1937         return 0;
1938 }