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