6cc1b37f10f0dc9b8aeb08df5778f418c1b8d1a4
[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_system_setting_h system_setting = NULL;
783         notification_setting_h setting = NULL;
784
785         if (noti == NULL) {
786                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
787                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
788                 goto out;
789         }
790
791         /* Get system setting */
792         if ((err = noti_system_setting_load_system_setting(&system_setting, noti->uid)) != NOTIFICATION_ERROR_NONE) {
793                 NOTIFICATION_ERR("noti_system_setting_load_system_setting failed [%d]", err);
794                 goto out;
795         }
796
797         if ((err = notification_system_setting_get_do_not_disturb(system_setting, &do_not_disturb)) != NOTIFICATION_ERROR_NONE) {
798                 NOTIFICATION_ERR("notification_system_setting_get_do_not_disturb failed [%d]", err);
799                 goto out;
800         }
801
802         NOTIFICATION_DBG("do_not_disturb [%d]", do_not_disturb);
803
804         if (do_not_disturb) {
805                 /* Check exception option of the caller package */
806                 err = noti_setting_service_get_setting_by_package_name(noti->caller_pkgname, &setting, noti->uid);
807
808                 if (err != NOTIFICATION_ERROR_NONE) {
809                         /* Retry with package id */
810                         err = _get_package_id_by_app_id(noti->caller_pkgname, &package_id);
811
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("noti_setting_service_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
847 out:
848         SAFE_FREE(package_id);
849
850         if (system_setting)
851                 notification_system_setting_free_system_setting(system_setting);
852
853         if (setting)
854                 notification_setting_free_notification(setting);
855
856         return err;
857 }
858
859 EXPORT_API int notification_noti_insert(notification_h noti)
860 {
861         int ret = 0;
862         sqlite3 *db = NULL;
863         sqlite3_stmt *stmt = NULL;
864         char *query = NULL;
865         char buf_key[32] = { 0, };
866         char *title_key = NULL;
867
868         if (noti == NULL) {
869                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
870                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
871         }
872
873         if (_is_allowed_to_notify((const char *)noti->caller_pkgname, noti->uid) == false) {
874                 NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
875                 return NOTIFICATION_ERROR_PERMISSION_DENIED;
876         }
877
878         if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE)
879                 NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
880
881
882         /* Open DB */
883         db = notification_db_open(DBPATH);
884         if (!db)
885                 return get_last_result();
886
887         /* Initialize private ID */
888         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
889         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
890
891         /* make query */
892         ret = _insertion_query_create(noti, &query);
893         if (ret != NOTIFICATION_ERROR_NONE)
894                 goto err;
895
896         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
897         if (ret != SQLITE_OK) {
898                 NOTIFICATION_ERR("Insert Query : %s", query);
899                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
900                                  sqlite3_errmsg(db));
901                 ret = NOTIFICATION_ERROR_FROM_DB;
902                 goto err;
903         }
904
905         /* Get title key */
906         if (noti->b_key != NULL) {
907                 snprintf(buf_key, sizeof(buf_key), "%d",
908                          NOTIFICATION_TEXT_TYPE_TITLE);
909
910                 bundle_get_str(noti->b_key, buf_key, &title_key);
911         }
912
913         if (title_key == NULL && noti->b_text != NULL) {
914                 snprintf(buf_key, sizeof(buf_key), "%d",
915                          NOTIFICATION_TEXT_TYPE_TITLE);
916
917                 bundle_get_str(noti->b_text, buf_key, &title_key);
918         }
919
920         if (title_key == NULL)
921                 title_key = noti->caller_pkgname;
922
923         /* Bind query */
924         ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
925         if (ret != NOTIFICATION_ERROR_NONE) {
926                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
927                 goto err;
928         }
929         ret = _notification_noti_bind_query_text(stmt, "$title_key", title_key);
930         if (ret != NOTIFICATION_ERROR_NONE) {
931                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
932                 goto err;
933         }
934         ret = _notification_noti_bind_query_double(stmt, "$progress_size", noti->progress_size);
935         if (ret != NOTIFICATION_ERROR_NONE) {
936                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
937                 goto err;
938         }
939         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage", noti->progress_percentage);
940         if (ret != NOTIFICATION_ERROR_NONE) {
941                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
942                 goto err;
943         }
944
945         ret = sqlite3_step(stmt);
946         if (ret == SQLITE_OK || ret == SQLITE_DONE) {
947                 noti->priv_id = (int)sqlite3_last_insert_rowid(db);
948
949                 if (_notification_noti_update_priv_id(db, noti->priv_id) == 0)
950                         ret = NOTIFICATION_ERROR_NONE;
951                 else
952                         ret = NOTIFICATION_ERROR_FROM_DB;
953
954         } else {
955                 ret = NOTIFICATION_ERROR_FROM_DB;
956         }
957 err:
958         if (stmt)
959                 sqlite3_finalize(stmt);
960
961         /* Close DB */
962         if (db)
963                 notification_db_close(&db);
964
965         if (query)
966                 sqlite3_free(query);
967
968         return ret;
969 }
970
971 /* LCOV_EXCL_START */
972 EXPORT_API int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id, uid_t uid)
973 {
974         int ret = 0;
975         char *query = NULL;
976         sqlite3 *db = NULL;
977         sqlite3_stmt *stmt = NULL;
978
979         if (priv_id < 0 || noti == NULL) {
980                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
981                 goto err;
982         }
983
984         /* Open DB */
985         db = notification_db_open(DBPATH);
986         if (!db)
987                 return get_last_result();
988
989         char *base_query = "select "
990                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
991                          "tag, b_text, b_key, b_format_args, num_format_args, "
992                          "text_domain, text_dir, time, insert_time, args, group_args, "
993                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
994                          "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
995                          "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
996                          "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
997                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
998                          "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
999                          "from noti_list ";
1000
1001         if (pkgname != NULL && strlen(pkgname) != 0)
1002                 query = sqlite3_mprintf("%s where caller_pkgname = '%s' and priv_id = %d and uid = %d",
1003                                 base_query, pkgname, priv_id, uid);
1004         else
1005                 query = sqlite3_mprintf("%s where priv_id = %d and uid = %d", base_query,  priv_id, uid);
1006
1007         if (query == NULL) {
1008                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1009                 goto err;
1010         }
1011
1012         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
1013         if (ret != SQLITE_OK) {
1014                 NOTIFICATION_ERR("select Query : %s", query);
1015                 NOTIFICATION_ERR("select DB error(%d) : %s", ret,
1016                                  sqlite3_errmsg(db));
1017                 ret = NOTIFICATION_ERROR_FROM_DB;
1018                 goto err;
1019         }
1020
1021         ret = sqlite3_step(stmt);
1022         if (ret == SQLITE_ROW) {
1023                 _notification_noti_populate_from_stmt(stmt, noti);
1024                 ret = NOTIFICATION_ERROR_NONE;
1025         } else {
1026                 ret = NOTIFICATION_ERROR_FROM_DB;
1027         }
1028
1029 err:
1030         if (query)
1031                 sqlite3_free(query);
1032
1033         if (stmt)
1034                 sqlite3_finalize(stmt);
1035
1036         /* Close DB */
1037         if (db != NULL)
1038                 notification_db_close(&db);
1039
1040         return ret;
1041 }
1042 /* LCOV_EXCL_STOP */
1043
1044 EXPORT_API int notification_noti_get_by_tag(notification_h noti, char *pkgname, char* tag, uid_t uid)
1045 {
1046         int ret = 0;
1047         sqlite3 *db = NULL;
1048         sqlite3_stmt *stmt = NULL;
1049
1050         if (tag == NULL || noti == NULL) {
1051                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1052                 goto err;
1053         }
1054
1055         /* Open DB */
1056         db = notification_db_open(DBPATH);
1057         if (!db)
1058                 return get_last_result();
1059
1060         if (pkgname != NULL && strlen(pkgname) != 0) {
1061                 ret = sqlite3_prepare_v2(db, "select "
1062                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1063                          "tag, b_text, b_key, b_format_args, num_format_args, "
1064                          "text_domain, text_dir, time, insert_time, args, group_args, "
1065                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1066                          "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
1067                          "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
1068                          "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
1069                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1070                          "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
1071                          "from noti_list where caller_pkgname = ? and tag = ? and uid = ?", -1, &stmt, NULL);
1072                 if (ret != SQLITE_OK) {
1073                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1074                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1075                 }
1076
1077                 ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
1078                 if (ret != SQLITE_OK) {
1079                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1080                         goto err;
1081                 }
1082
1083                 ret = sqlite3_bind_text(stmt, 2,  tag, -1, SQLITE_TRANSIENT);
1084                 if (ret != SQLITE_OK) {
1085                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1086                         goto err;
1087                 }
1088
1089                 ret = sqlite3_bind_int(stmt, 3, uid);
1090                 if (ret != SQLITE_OK) {
1091                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1092                         goto err;
1093                 }
1094
1095         } else {
1096                 ret = sqlite3_prepare_v2(db, "select "
1097                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1098                          "tag, b_text, b_key, b_format_args, num_format_args, "
1099                          "text_domain, text_dir, time, insert_time, args, group_args, "
1100                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1101                          "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
1102                          "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
1103                          "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
1104                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1105                          "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
1106                          "from noti_list where  tag = ? and uid = ?", -1, &stmt, NULL);
1107                 if (ret != SQLITE_OK) {
1108                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1109                         return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1110                 }
1111
1112                 ret = sqlite3_bind_text(stmt, 1, tag, -1, SQLITE_TRANSIENT);
1113                 if (ret != SQLITE_OK) {
1114                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1115                         goto err;
1116                 }
1117
1118                 ret = sqlite3_bind_int(stmt, 2, uid);
1119                 if (ret != SQLITE_OK) {
1120                         NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1121                         goto err;
1122                 }
1123         }
1124
1125         ret = sqlite3_step(stmt);
1126         if (ret == SQLITE_ROW) {
1127                 _notification_noti_populate_from_stmt(stmt, noti);
1128                 ret = NOTIFICATION_ERROR_NONE;
1129         } else {
1130                 ret = NOTIFICATION_ERROR_FROM_DB;
1131         }
1132
1133 err:
1134
1135         if (stmt)
1136                 sqlite3_finalize(stmt);
1137
1138         /* Close DB */
1139         if (db != NULL)
1140                 notification_db_close(&db);
1141
1142         return ret;
1143 }
1144
1145 EXPORT_API int notification_noti_update(notification_h noti)
1146 {
1147         int ret = 0;
1148         sqlite3 *db;
1149         sqlite3_stmt *stmt = NULL;
1150         char *query = NULL;
1151
1152         /* Open DB */
1153         db = notification_db_open(DBPATH);
1154         if (!db)
1155                 return get_last_result();
1156
1157         if (_is_allowed_to_notify((const char *)noti->caller_pkgname, noti->uid) == false) {
1158                 NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
1159                 return NOTIFICATION_ERROR_PERMISSION_DENIED;
1160         }
1161
1162         if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE)
1163                 NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
1164
1165         /* Check private ID is exist */
1166         ret = _notification_noti_check_priv_id(noti, db);
1167         if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
1168                 ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
1169                 goto err;
1170         }
1171
1172         /* make update query */
1173         ret = _update_query_create(noti, &query);
1174         if (ret != NOTIFICATION_ERROR_NONE)
1175                 goto err;
1176
1177         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
1178         if (ret != SQLITE_OK) {
1179                 NOTIFICATION_ERR("Insert Query : %s", query);
1180                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
1181                                  sqlite3_errmsg(db));
1182                 ret = NOTIFICATION_ERROR_FROM_DB;
1183                 goto err;
1184         }
1185
1186         ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
1187         if (ret != NOTIFICATION_ERROR_NONE) {
1188                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
1189                 goto err;
1190         }
1191
1192         ret = _notification_noti_bind_query_double(stmt, "$progress_size", noti->progress_size);
1193         if (ret != NOTIFICATION_ERROR_NONE) {
1194                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
1195                 goto err;
1196         }
1197
1198         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage", noti->progress_percentage);
1199         if (ret != NOTIFICATION_ERROR_NONE) {
1200                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
1201                 goto err;
1202         }
1203
1204         ret = sqlite3_step(stmt);
1205         if (ret == SQLITE_OK || ret == SQLITE_DONE)
1206                 ret = NOTIFICATION_ERROR_NONE;
1207         else
1208                 ret = NOTIFICATION_ERROR_FROM_DB;
1209
1210 err:
1211         if (stmt)
1212                 sqlite3_finalize(stmt);
1213
1214         /* Close DB */
1215         if (db)
1216                 notification_db_close(&db);
1217
1218         if (query)
1219                 sqlite3_free(query);
1220
1221         return ret;
1222 }
1223
1224 EXPORT_API int notification_noti_delete_all(notification_type_e type, const char *pkgname, int *num_deleted, int **list_deleted_rowid, uid_t uid)
1225 {
1226         int ret = NOTIFICATION_ERROR_NONE;
1227         int ret_tmp = NOTIFICATION_ERROR_NONE;
1228         int i = 0, data_cnt = 0;
1229         sqlite3 *db = NULL;
1230         sqlite3_stmt *stmt = NULL;
1231         char buf[128] = { 0, };
1232         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1233         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1234         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1235         char err_buf[ERR_BUFFER_SIZE];
1236
1237         /* Open DB */
1238         db = notification_db_open(DBPATH);
1239         if (!db)
1240                 return get_last_result();
1241
1242         if (pkgname == NULL || strlen(pkgname) == 0) {
1243                 if (type != NOTIFICATION_TYPE_NONE)
1244                         snprintf(query_where, sizeof(query_where),
1245                                  "where type = %d and uid = %d", type, uid);
1246
1247         } else {
1248                 if (type == NOTIFICATION_TYPE_NONE)
1249                         snprintf(query_where, sizeof(query_where),
1250                                  "where caller_pkgname = '%s' and uid = %d", pkgname, uid);
1251                 else
1252                         snprintf(query_where, sizeof(query_where),
1253                                  "where caller_pkgname = '%s' and type = %d and uid = %d",
1254                                  pkgname, type, uid);
1255
1256         }
1257
1258         if (num_deleted != NULL)
1259                 *num_deleted = 0;
1260
1261         if (list_deleted_rowid != NULL) {
1262                 *list_deleted_rowid = NULL;
1263                 snprintf(query, sizeof(query),
1264                                 "select priv_id from noti_list %s ", query_where);
1265
1266                 ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1267                 if (ret != SQLITE_OK) {
1268                         NOTIFICATION_ERR("Select Query : %s", query);
1269                         NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1270                                          sqlite3_errmsg(db));
1271
1272                         ret = NOTIFICATION_ERROR_FROM_DB;
1273                         goto err;
1274                 }
1275
1276                 while (sqlite3_step(stmt) == SQLITE_ROW) {
1277                         if (data_cnt % 8 == 0) {
1278                                 int *tmp;
1279
1280                                 tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
1281                                 if (tmp) {
1282                                         *list_deleted_rowid = tmp;
1283                                 } else {
1284                                         NOTIFICATION_ERR("Heap: %s\n", strerror_r(errno, err_buf, sizeof(err_buf)));
1285                                         /*!
1286                                          * \TODO
1287                                          * How can I handle this?
1288                                          */
1289                                         free(*list_deleted_rowid);
1290                                         *list_deleted_rowid = NULL;
1291                                         ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1292                                         goto err;
1293                                 }
1294                         }
1295                         *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
1296                         data_cnt++;
1297                 }
1298
1299                 if (stmt) {
1300                         sqlite3_finalize(stmt);
1301                         stmt = NULL;
1302                 }
1303
1304                 if (data_cnt > 0) {
1305                         query_where[0] = '\0';
1306                         snprintf(query_base, sizeof(query_base) - 1, "delete from noti_list");
1307                         for (i = 0; i < data_cnt ; i++) {
1308                                 if (i % NOTI_BURST_DELETE_UNIT == 0 && i != 0) {
1309                                         snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1310                                         ret_tmp = notification_db_exec(db, query, NULL);
1311                                         query_where[0] = '\0';
1312                                         if (ret == NOTIFICATION_ERROR_NONE)
1313                                                 ret = ret_tmp;
1314
1315                                 }
1316                                 snprintf(buf, sizeof(buf) - 1, "%s%d", (i % NOTI_BURST_DELETE_UNIT == 0) ? "" : ",", *((*list_deleted_rowid) + i));
1317                                 strncat(query_where, buf, sizeof(query_where) - strlen(query_where) - 1);
1318                         }
1319                         if ((i <= NOTI_BURST_DELETE_UNIT) || ((i % NOTI_BURST_DELETE_UNIT) > 0)) {
1320                                 snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1321                                 ret_tmp = notification_db_exec(db, query, NULL);
1322                                 if (ret == NOTIFICATION_ERROR_NONE)
1323                                         ret = ret_tmp;
1324                         }
1325                 } else {
1326                         free(*list_deleted_rowid);
1327                         *list_deleted_rowid = NULL;
1328                 }
1329
1330                 if (num_deleted != NULL)
1331                         *num_deleted = data_cnt;
1332
1333         } else {
1334                 /* Make main query */
1335                 snprintf(query_base, sizeof(query_base), "delete from noti_list ");
1336                 snprintf(query, sizeof(query), "%s %s", query_base, query_where);
1337
1338                 ret = notification_db_exec(db, query, NULL);
1339
1340                 if (num_deleted != NULL)
1341                         *num_deleted = sqlite3_changes(db);
1342
1343         }
1344
1345 err:
1346         if (stmt)
1347                 sqlite3_finalize(stmt);
1348
1349         /* Close DB */
1350         if (db)
1351                 notification_db_close(&db);
1352
1353         return ret;
1354 }
1355
1356 /* LCOV_EXCL_START */
1357 EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
1358 {
1359         sqlite3 *db = NULL;
1360         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1361         int ret;
1362
1363         /* Check pkgname is valid */
1364         if (pkgname == NULL)
1365                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1366
1367         /* Open DB */
1368         db = notification_db_open(DBPATH);
1369         if (!db)
1370                 return get_last_result();
1371
1372         /* Make query */
1373         snprintf(query, sizeof(query), "delete from noti_list "
1374                  "where caller_pkgname = '%s' and priv_id = %d", pkgname,
1375                  priv_id);
1376
1377         /* execute DB */
1378         ret = notification_db_exec(db, query, NULL);
1379
1380         /* Close DB */
1381         if (db)
1382                 notification_db_close(&db);
1383
1384         return ret;
1385 }
1386 /* LCOV_EXCL_STOP */
1387
1388 EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgname, int priv_id, int *num_changes, uid_t uid)
1389 {
1390         sqlite3 *db = NULL;
1391         char query[NOTIFICATION_QUERY_MAX] = {0, };
1392         int ret;
1393
1394         /* Check pkgname is valid */
1395         if (pkgname == NULL || strlen(pkgname) == 0)
1396                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1397
1398         /* Open DB */
1399         db = notification_db_open(DBPATH);
1400         if (!db)
1401                 return get_last_result();
1402
1403         /* Make query */
1404         snprintf(query, sizeof(query), "delete from noti_list "
1405                  "where caller_pkgname = '%s' and priv_id = %d and uid = %d", pkgname,
1406                  priv_id, uid);
1407         NOTIFICATION_DBG("%s", query);
1408
1409         /* execute DB */
1410         ret = notification_db_exec(db, query, num_changes);
1411
1412         if (num_changes != NULL)
1413                 NOTIFICATION_DBG("deleted num:%d", *num_changes);
1414
1415         /* Close DB */
1416         if (db)
1417                 notification_db_close(&db);
1418
1419         return ret;
1420 }
1421
1422 /* todo refactoring */
1423 /* LCOV_EXCL_START */
1424 EXPORT_API int notification_noti_get_count(notification_type_e type,
1425                                                  const char *pkgname,
1426                                                  int group_id, int priv_id,
1427                                                  int *count, uid_t uid)
1428 {
1429         sqlite3 *db = NULL;
1430         sqlite3_stmt *stmt = NULL;
1431         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1432         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1433         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1434         char query_where_more[NOTIFICATION_QUERY_MAX] = { 0, };
1435
1436         int ret = 0, get_count = 0, internal_group_id = 0;
1437         int status = VCONFKEY_TELEPHONY_SIM_UNKNOWN;
1438         int flag_where_more = 0;
1439         int ret_vconf = 0;
1440
1441         /* Open DB */
1442         db = notification_db_open(DBPATH);
1443         if (!db)
1444                 return get_last_result();
1445
1446         /* Check current sim status */
1447         ret_vconf = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1448
1449         /* Make query */
1450         snprintf(query_base, sizeof(query_base),
1451                  "select count(*) from noti_list ");
1452
1453         if (pkgname != NULL && strlen(pkgname) != 0) {
1454                 if (group_id == NOTIFICATION_GROUP_ID_NONE) {
1455                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1456                                 snprintf(query_where, sizeof(query_where),
1457                                          "where caller_pkgname = '%s' and uid = %d ",
1458                                          pkgname, uid);
1459                         } else {
1460                                 internal_group_id =
1461                                     _notification_noti_get_internal_group_id_by_priv_id
1462                                     (pkgname, priv_id, db);
1463                                 snprintf(query_where, sizeof(query_where),
1464                                          "where caller_pkgname = '%s' and internal_group_id = %d and uid = %d ",
1465                                          pkgname, internal_group_id, uid);
1466                         }
1467                 } else {
1468                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1469                                 snprintf(query_where, sizeof(query_where),
1470                                          "where caller_pkgname = '%s' and group_id = %d and uid = %d ",
1471                                          pkgname, group_id, uid);
1472                         } else {
1473                                 internal_group_id =
1474                                     _notification_noti_get_internal_group_id_by_priv_id
1475                                     (pkgname, priv_id, db);
1476                                 snprintf(query_where, sizeof(query_where),
1477                                          "where caller_pkgname = '%s' and internal_group_id = %d and uid = %d ",
1478                                          pkgname, internal_group_id, uid);
1479                         }
1480                 }
1481         } else {
1482                 snprintf(query_where, sizeof(query_where), "where uid = %d", uid);
1483         }
1484
1485         if (ret_vconf == 0 && status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1486                 if (type != NOTIFICATION_TYPE_NONE) {
1487                         snprintf(query_where_more, sizeof(query_where_more),
1488                                  "type = %d ", type);
1489                         flag_where_more = 1;
1490                 }
1491         } else {
1492                 if (type != NOTIFICATION_TYPE_NONE) {
1493                         snprintf(query_where_more, sizeof(query_where_more),
1494                                  "type = %d and flag_simmode = 0 ", type);
1495                         flag_where_more = 1;
1496                 } else {
1497                         snprintf(query_where_more, sizeof(query_where_more),
1498                                  "flag_simmode = 0 ");
1499                         flag_where_more = 1;
1500                 }
1501         }
1502
1503         if (flag_where_more == 1) {
1504                 snprintf(query, sizeof(query), "%s %s and %s",
1505                          query_base, query_where, query_where_more);
1506         } else {
1507                 snprintf(query, sizeof(query), "%s %s", query_base,
1508                          query_where);
1509         }
1510
1511         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1512         if (ret != SQLITE_OK) {
1513                 NOTIFICATION_ERR("Select Query : %s", query);
1514                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1515                                  sqlite3_errmsg(db));
1516
1517                 ret = NOTIFICATION_ERROR_FROM_DB;
1518                 goto err;
1519         }
1520
1521         ret = sqlite3_step(stmt);
1522         if (ret == SQLITE_ROW)
1523                 get_count = sqlite3_column_int(stmt, 0);
1524
1525         ret = NOTIFICATION_ERROR_NONE;
1526
1527 err:
1528         if (stmt)
1529                 sqlite3_finalize(stmt);
1530
1531
1532         /* Close DB */
1533         if (db)
1534                 notification_db_close(&db);
1535
1536         *count = get_count;
1537
1538         return ret;
1539 }
1540 /* LCOV_EXCL_STOP */
1541
1542 EXPORT_API int notification_noti_get_grouping_list(notification_type_e type,
1543                                                          int count,
1544                                                          notification_list_h *list,
1545                                                          uid_t uid)
1546 {
1547         sqlite3 *db = NULL;
1548         sqlite3_stmt *stmt = NULL;
1549         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1550         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1551         char query_uid[NOTIFICATION_QUERY_MAX] = { 0, };
1552         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1553
1554         int ret = 0;
1555         notification_list_h get_list = NULL;
1556         notification_h noti = NULL;
1557         int internal_count = 0;
1558         int status;
1559
1560         /* Open DB */
1561         db = notification_db_open(DBPATH);
1562         if (!db)
1563                 return get_last_result();
1564
1565         /* Check current sim status */
1566         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1567
1568         /* Make query */
1569         snprintf(query_base, sizeof(query_base), "select "
1570                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1571                  "tag, b_text, b_key, b_format_args, num_format_args, "
1572                  "text_domain, text_dir, time, insert_time, args, group_args, "
1573                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1574                  "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
1575                  "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
1576                  "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
1577                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1578                  "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
1579                  "from noti_list where 1 > 0 ");
1580
1581         if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1582                 if (type != NOTIFICATION_TYPE_NONE)
1583                         snprintf(query_where, sizeof(query_where),
1584                                  " and type = %d ", type);
1585         } else {
1586                 if (type != NOTIFICATION_TYPE_NONE)
1587                         snprintf(query_where, sizeof(query_where),
1588                                  " and type = %d and flag_simmode = 0 ", type);
1589                 else
1590                         snprintf(query_where, sizeof(query_where),
1591                                  " and flag_simmode = 0 ");
1592         }
1593
1594         if (uid != NOTIFICATION_GLOBAL_UID)
1595                 snprintf(query_uid, sizeof(query_uid), " and uid = %d ", uid);
1596
1597         snprintf(query, sizeof(query),
1598                  "%s %s %s "
1599                  "group by internal_group_id "
1600                  "order by rowid desc, time desc", query_base, query_where, query_uid);
1601
1602         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1603         if (ret != SQLITE_OK) {
1604                 NOTIFICATION_ERR("Select Query : %s", query);
1605                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1606                                  sqlite3_errmsg(db));
1607
1608                 ret = NOTIFICATION_ERROR_FROM_DB;
1609                 goto err;
1610         }
1611
1612         while (sqlite3_step(stmt) == SQLITE_ROW) {
1613                 /* Make notification list */
1614                 noti = _notification_noti_get_item(stmt);
1615                 if (noti != NULL) {
1616                         internal_count++;
1617
1618                         get_list = notification_list_append(get_list, noti);
1619
1620                         if (count != -1 && internal_count >= count) {
1621                                 NOTIFICATION_INFO
1622                                     ("internal count %d >= count %d",
1623                                      internal_count, count);
1624                                 break;
1625                         }
1626                 }
1627         }
1628
1629         ret = NOTIFICATION_ERROR_NONE;
1630
1631 err:
1632         if (stmt)
1633                 sqlite3_finalize(stmt);
1634
1635         /* Close DB */
1636         if (db)
1637                 notification_db_close(&db);
1638
1639         if (get_list != NULL)
1640                 *list = notification_list_get_head(get_list);
1641         return ret;
1642 }
1643
1644 EXPORT_API int notification_noti_get_detail_list(const char *pkgname,
1645                                                        int group_id,
1646                                                        int priv_id, int count,
1647                                                        notification_list_h *list,
1648                                                        uid_t uid)
1649 {
1650         sqlite3 *db = NULL;
1651         sqlite3_stmt *stmt = NULL;
1652         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1653         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1654
1655         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1656         int ret = 0;
1657         notification_list_h get_list = NULL;
1658         notification_h noti = NULL;
1659         int internal_count = 0;
1660         int internal_group_id = 0;
1661         int status = 0; /* If the vconf_get_int failed, the status will be the garbage value */
1662
1663         /* Open DB */
1664         db = notification_db_open(DBPATH);
1665         if (!db)
1666                 return get_last_result();
1667
1668         /* Check current sim status */
1669         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1670
1671         /* Make query */
1672         snprintf(query_base, sizeof(query_base), "select "
1673                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1674                  "tag, b_text, b_key, b_format_args, num_format_args, "
1675                  "text_domain, text_dir, time, insert_time, args, group_args, "
1676                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1677                  "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
1678                  "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
1679                  "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
1680                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1681                  "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
1682                  "from noti_list ");
1683
1684         if (priv_id == NOTIFICATION_PRIV_ID_NONE && group_id == NOTIFICATION_GROUP_ID_NONE) {
1685                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED)
1686                         snprintf(query_where, sizeof(query_where),
1687                                  "where  caller_pkgname = '%s' and uid = %d ", pkgname, uid);
1688                 else
1689                         snprintf(query_where, sizeof(query_where),
1690                                  "where  caller_pkgname = '%s' and flag_simmode = 0 and uid = %d ", pkgname, uid);
1691
1692         } else {
1693                 internal_group_id =
1694                     _notification_noti_get_internal_group_id_by_priv_id(pkgname,
1695                                                                         priv_id, db);
1696
1697                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED)
1698                         snprintf(query_where, sizeof(query_where),
1699                                  "where  caller_pkgname = '%s' and internal_group_id = %d and uid = %d ",
1700                                  pkgname, internal_group_id, uid);
1701                 else
1702                         snprintf(query_where, sizeof(query_where),
1703                                  "where  caller_pkgname = '%s' and internal_group_id = %d and flag_simmode = 0 and uid = %d ",
1704                                  pkgname, internal_group_id, uid);
1705         }
1706
1707         snprintf(query, sizeof(query),
1708                  "%s %s "
1709                  "order by rowid desc, time desc", query_base, query_where);
1710
1711         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1712         if (ret != SQLITE_OK) {
1713                 NOTIFICATION_ERR("Select Query : %s", query);
1714                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1715                                  sqlite3_errmsg(db));
1716
1717                 ret = NOTIFICATION_ERROR_FROM_DB;
1718                 goto err;
1719         }
1720
1721         while (sqlite3_step(stmt) == SQLITE_ROW) {
1722                 /* Make notification list */
1723                 noti = _notification_noti_get_item(stmt);
1724                 if (noti != NULL) {
1725                         internal_count++;
1726
1727                         get_list = notification_list_append(get_list, noti);
1728
1729                         if (count != -1 && internal_count >= count) {
1730                                 NOTIFICATION_INFO
1731                                     ("internal count %d >= count %d",
1732                                      internal_count, count);
1733                                 break;
1734                         }
1735                 }
1736         }
1737
1738         ret = NOTIFICATION_ERROR_NONE;
1739
1740 err:
1741         if (stmt)
1742                 sqlite3_finalize(stmt);
1743
1744         /* Close DB */
1745         if (db)
1746                 notification_db_close(&db);
1747
1748         if (get_list != NULL)
1749                 *list = notification_list_get_head(get_list);
1750
1751         return ret;
1752 }
1753
1754 EXPORT_API int notification_noti_check_tag(notification_h noti)
1755 {
1756         int result = 0;
1757         int ret = NOTIFICATION_ERROR_NONE;
1758         sqlite3 *db;
1759         sqlite3_stmt *stmt = NULL;
1760
1761         if (noti->tag == NULL)
1762                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
1763
1764         /* Open DB */
1765         db = notification_db_open(DBPATH);
1766         if (!db)
1767                 return get_last_result();
1768
1769         ret = sqlite3_prepare_v2(db, "SELECT priv_id FROM noti_list WHERE caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
1770         if (ret != SQLITE_OK) {
1771                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1772                 if (db)
1773                         notification_db_close(&db);
1774                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
1775         }
1776
1777         ret = sqlite3_bind_text(stmt, 1, noti->caller_pkgname, -1, SQLITE_TRANSIENT);
1778         if (ret != SQLITE_OK) {
1779                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1780                 goto err;
1781         }
1782
1783         ret = sqlite3_bind_text(stmt, 2, noti->tag, -1, SQLITE_TRANSIENT);
1784         if (ret != SQLITE_OK) {
1785                 NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
1786                 goto err;
1787         }
1788
1789         ret = sqlite3_step(stmt);
1790         if (ret == SQLITE_ROW)
1791                 result = sqlite3_column_int(stmt, 0);
1792         else
1793                 result = 0;
1794
1795         sqlite3_finalize(stmt);
1796
1797         /* If result > 0, there is priv_id in DB */
1798         if (result > 0) {
1799                 noti->priv_id = result;
1800                 ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
1801         } else {
1802                 ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
1803         }
1804
1805 err:
1806         if (db)
1807                 notification_db_close(&db);
1808
1809         return ret;
1810 }
1811