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