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