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