Using gdbus for IPC instead of com-core package
[platform/core/api/notification.git] / src / notification_setting.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 #include <db-util.h>
26 #include <package_manager.h>
27 #include <pkgmgr-info.h>
28 #include <tizen_type.h>
29
30 #include <notification.h>
31 #include <notification_db.h>
32 #include <notification_list.h>
33 #include <notification_noti.h>
34 #include <notification_debug.h>
35 #include <notification_ipc.h>
36 #include <notification_private.h>
37 #include <notification_setting.h>
38 #include <notification_setting_internal.h>
39
40 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
41
42
43
44 EXPORT_API int notification_setting_get_setting_array(notification_setting_h *setting_array, int *count)
45 {
46         int ret = NOTIFICATION_ERROR_NONE;
47         if (setting_array == NULL || count == NULL) {
48                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
49                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
50         }
51         ret = notification_ipc_request_get_setting_array(setting_array, count);
52         return ret;
53 }
54
55 EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting)
56 {
57         int ret = NOTIFICATION_ERROR_NONE;
58         if (package_name == NULL || setting == NULL) {
59                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
60                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
61         }
62         ret = notification_ipc_request_get_setting_by_package_name(package_name, setting);
63         return ret;
64 }
65
66 EXPORT_API int notification_setting_get_setting(notification_setting_h *setting)
67 {
68         int ret;
69         char *package_name = NULL;
70
71         package_name = notification_get_pkgname_by_pid();
72
73         if (package_name == NULL)
74                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
75
76         ret = notification_setting_get_setting_by_package_name(package_name, setting);
77
78         free(package_name);
79
80         return ret;
81 }
82
83 EXPORT_API int notification_setting_get_package_name(notification_setting_h setting, char **value)
84 {
85         int err = NOTIFICATION_ERROR_NONE;
86
87         if (setting == NULL || value == NULL) {
88                 NOTIFICATION_ERR("Invalid parameter\n");
89                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
90                 goto out;
91         }
92
93         if (setting->package_name == NULL) {
94                 NOTIFICATION_ERR("setting->package_name is null\n");
95                 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
96                 goto out;
97         }
98
99         *value = SAFE_STRDUP(setting->package_name);
100
101 out:
102
103         return err;
104 }
105
106 EXPORT_API int notification_setting_set_package_name(notification_setting_h setting, char *value)
107 {
108         int err = NOTIFICATION_ERROR_NONE;
109
110         if (setting == NULL || value == NULL) {
111                 NOTIFICATION_ERR("Invalid parameter\n");
112                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
113                 goto out;
114         }
115
116         if (setting->package_name != NULL)
117                 free(setting->package_name);
118
119         setting->package_name = SAFE_STRDUP(value);
120
121 out:
122
123         return err;
124 }
125
126 EXPORT_API int notification_setting_get_allow_to_notify(notification_setting_h setting, bool *value)
127 {
128         int err = NOTIFICATION_ERROR_NONE;
129
130         if (setting == NULL || value == NULL) {
131                 NOTIFICATION_ERR("Invalid parameter\n");
132                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
133                 goto out;
134         }
135
136         *value = setting->allow_to_notify;
137
138 out:
139
140         return err;
141 }
142
143 EXPORT_API int notification_setting_set_allow_to_notify(notification_setting_h setting, bool value)
144 {
145         int err = NOTIFICATION_ERROR_NONE;
146
147         if (setting == NULL) {
148                 NOTIFICATION_ERR("Invalid parameter\n");
149                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
150                 goto out;
151         }
152
153         setting->allow_to_notify = value;
154
155 out:
156
157         return err;
158 }
159
160 EXPORT_API int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value)
161 {
162         int err = NOTIFICATION_ERROR_NONE;
163
164         if (setting == NULL || value == NULL) {
165                 NOTIFICATION_ERR("Invalid parameter\n");
166                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
167                 goto out;
168         }
169
170         *value = setting->do_not_disturb_except;
171
172 out:
173
174         return err;
175 }
176
177 EXPORT_API int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value)
178 {
179         int err = NOTIFICATION_ERROR_NONE;
180
181         if (setting == NULL) {
182                 NOTIFICATION_ERR("Invalid parameter\n");
183                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
184                 goto out;
185         }
186
187         setting->do_not_disturb_except = value;
188
189 out:
190
191         return err;
192 }
193
194 EXPORT_API int notification_setting_get_visibility_class(notification_setting_h setting, int *value)
195 {
196         int err = NOTIFICATION_ERROR_NONE;
197
198         if (setting == NULL || value == NULL) {
199                 NOTIFICATION_ERR("Invalid parameter\n");
200                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
201                 goto out;
202         }
203
204         *value = setting->visibility_class;
205
206 out:
207
208         return err;
209 }
210
211 EXPORT_API int notification_setting_set_visibility_class(notification_setting_h setting, int value)
212 {
213         int err = NOTIFICATION_ERROR_NONE;
214
215         if (setting == NULL) {
216                 NOTIFICATION_ERR("Invalid parameter\n");
217                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
218                 goto out;
219         }
220
221         setting->visibility_class = value;
222
223 out:
224
225         return err;
226 }
227
228 EXPORT_API int notification_setting_update_setting(notification_setting_h setting)
229 {
230         int err = NOTIFICATION_ERROR_NONE;
231
232         if (setting == NULL) {
233                 NOTIFICATION_ERR("Invalid parameter\n");
234                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
235                 goto out;
236         }
237
238         err = notification_ipc_update_setting(setting);
239         if (err != NOTIFICATION_ERROR_NONE) {
240                 NOTIFICATION_ERR("notification_setting_update_setting returns[%d]\n", err);
241                 goto out;
242         }
243
244 out:
245         return err;
246 }
247
248 EXPORT_API int notification_setting_free_notification(notification_setting_h setting)
249 {
250         int err = NOTIFICATION_ERROR_NONE;
251
252         if (setting == NULL) {
253                         NOTIFICATION_ERR("Invalid parameter\n");
254                         err = NOTIFICATION_ERROR_INVALID_PARAMETER;
255                         goto out;
256                 }
257
258         SAFE_FREE(setting->package_name);
259
260         /* add codes to free all properties */
261
262         SAFE_FREE(setting);
263 out:
264
265         return err;
266 }
267
268 EXPORT_API int notification_setting_db_update(const char *package_name, int allow_to_notify, int do_not_disturb_except, int visibility_class)
269 {
270         int err = NOTIFICATION_ERROR_NONE;
271         sqlite3 *db = NULL;
272         char *sqlbuf = NULL;
273         int sqlret;
274
275         if (package_name == NULL || strlen(package_name) == 0)
276                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
277
278         sqlret = db_util_open(DBPATH, &db, 0);
279         if (sqlret != SQLITE_OK || db == NULL) {
280                 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret);
281                 return NOTIFICATION_ERROR_FROM_DB;
282         }
283
284         sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_notify = %d, do_not_disturb_except = %d, visibility_class = %d " \
285                         "WHERE package_name = %Q",
286                         NOTIFICATION_SETTING_DB_TABLE, allow_to_notify, do_not_disturb_except, visibility_class, package_name);
287         if (!sqlbuf) {
288                 NOTIFICATION_ERR("fail to alloc query");
289                 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
290                 goto return_close_db;
291         }
292
293         err = notification_db_exec(db, sqlbuf, NULL);
294
295 return_close_db:
296         if (sqlbuf)
297                 sqlite3_free(sqlbuf);
298
299         sqlret = db_util_close(db);
300         if (sqlret != SQLITE_OK)
301                 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
302
303         return err;
304 }
305
306 static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name)
307 {
308         sqlite3_stmt *db_statement = NULL;
309         int sqlite3_ret = SQLITE_OK;
310         bool err = true;
311         int field_index = 1;
312
313         sqlite3_ret = sqlite3_prepare_v2(db, "SELECT package_name FROM notification_setting WHERE package_name = ?", -1, &db_statement, NULL);
314
315         if (sqlite3_ret != SQLITE_OK) {
316                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
317                 err = false;
318                 goto out;
319         }
320
321         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
322
323         sqlite3_ret = sqlite3_step(db_statement);
324
325         if (sqlite3_ret == SQLITE_DONE) {
326                 NOTIFICATION_INFO("no matched package_name found[%s][%d]", package_name, sqlite3_ret);
327                 err = false;
328                 goto out;
329         }
330
331         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
332                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
333                 err = false;
334                 goto out;
335         }
336 out:
337         if (db_statement)
338                 sqlite3_finalize(db_statement);
339
340         return err;
341 }
342
343 static int foreach_package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
344 {
345         sqlite3 *db = user_data;
346         sqlite3_stmt *db_statement = NULL;
347         char *package_name = NULL;
348         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
349         int sqlite3_ret = SQLITE_OK;
350         int field_index = 1;
351         int err = true;
352
353         if ((pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &package_name)) != PACKAGE_MANAGER_ERROR_NONE) {
354                 NOTIFICATION_ERR("package_info_get_package failed [%d]", pkgmgr_ret);
355                 err = false;
356                 goto out;
357         }
358
359         if (_is_package_in_setting_table(db, package_name) == true) {
360                 NOTIFICATION_INFO("[%s] is exist", package_name);
361                 goto out;
362         }
363
364         NOTIFICATION_INFO("[%s] will be inserted", package_name);
365
366         sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (package_name) VALUES (?) ", -1, &db_statement, NULL);
367
368         if (sqlite3_ret != SQLITE_OK) {
369                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
370                 err = false;
371                 goto out;
372         }
373
374         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
375
376         sqlite3_ret = sqlite3_step(db_statement);
377
378         NOTIFICATION_INFO("sqlite3_step returns[%d]", sqlite3_ret);
379
380         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
381                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
382                 err = false;
383         }
384
385 out:
386         if (db_statement)
387                 sqlite3_finalize(db_statement);
388
389         NOTIFICATION_INFO("foreach_package_info_callback returns[%d]", err);
390         return err;
391 }
392
393 EXPORT_API int notification_setting_refresh_setting_table()
394 {
395         int err = NOTIFICATION_ERROR_NONE;
396         sqlite3 *db = NULL;
397         int sqlite3_ret = SQLITE_OK;
398         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
399         pkgmgrinfo_pkginfo_filter_h filter;
400         uid_t current_uid;
401
402         sqlite3_ret = db_util_open(DBPATH, &db, 0);
403
404         if (sqlite3_ret != SQLITE_OK || db == NULL) {
405                 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
406                 err = NOTIFICATION_ERROR_FROM_DB;
407                 goto out;
408         }
409
410         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
411
412         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
413         if (pkgmgr_ret != PMINFO_R_OK) {
414                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
415                 err = NOTIFICATION_ERROR_FROM_DB;
416                 goto out;
417         }
418
419         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(filter, PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, NOTIFICATION_PRIVILEGE);
420         if (pkgmgr_ret != PMINFO_R_OK) {
421                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
422                 err = NOTIFICATION_ERROR_FROM_DB;
423                 goto out;
424         }
425
426         current_uid = getuid();
427
428         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, foreach_package_info_callback, db, current_uid);
429         if (pkgmgr_ret != PMINFO_R_OK) {
430                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
431                 err = NOTIFICATION_ERROR_FROM_DB;
432                 goto out;
433         }
434
435         pkgmgrinfo_pkginfo_filter_destroy(filter);
436
437
438 out:
439
440         if (db) {
441                 if (err == NOTIFICATION_ERROR_NONE)
442                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
443                 else
444                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
445
446                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
447                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
448         }
449
450         NOTIFICATION_INFO("notification_setting_refresh_setting_table returns [%08X]", err);
451
452         return err;
453 }
454
455 typedef enum {
456         OPERATION_TYPE_INSERT_RECORD = 0,
457         OPERATION_TYPE_DELETE_RECORD = 1,
458 } notification_setting_operation_type;
459
460 static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name)
461 {
462         sqlite3 *db = NULL;
463         sqlite3_stmt *db_statement = NULL;
464         int sqlite3_ret = SQLITE_OK;
465         int field_index = 1;
466         bool is_package_in_setting_table = false;
467         int err = NOTIFICATION_ERROR_NONE;
468
469         sqlite3_ret = db_util_open(DBPATH, &db, 0);
470
471         if (sqlite3_ret != SQLITE_OK || db == NULL) {
472                 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
473                 err = NOTIFICATION_ERROR_FROM_DB;
474                 goto out;
475         }
476
477         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
478
479         is_package_in_setting_table = _is_package_in_setting_table(db, package_name);
480
481         switch (operation_type) {
482         case OPERATION_TYPE_INSERT_RECORD:
483                 if (is_package_in_setting_table == true) {
484                         NOTIFICATION_INFO("[%s] is already exist", package_name);
485                         goto out;
486                 }
487                 NOTIFICATION_INFO("[%s] will be inserted", package_name);
488                 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (package_name) VALUES (?) ", -1, &db_statement, NULL);
489                 break;
490
491         case OPERATION_TYPE_DELETE_RECORD:
492                 if (is_package_in_setting_table == false) {
493                         NOTIFICATION_INFO("[%s] is not exist", package_name);
494                         goto out;
495                 }
496                 NOTIFICATION_INFO("[%s] will be removed", package_name);
497                 sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE package_name = ? ", -1, &db_statement, NULL);
498                 break;
499         default:
500                 break;
501         }
502
503         if (sqlite3_ret != SQLITE_OK) {
504                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
505                 err = NOTIFICATION_ERROR_FROM_DB;
506                 goto out;
507         }
508
509         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
510
511         sqlite3_ret = sqlite3_step(db_statement);
512
513         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
514                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
515                 err = NOTIFICATION_ERROR_FROM_DB;
516         }
517
518 out:
519         if (db_statement)
520                 sqlite3_finalize(db_statement);
521
522         if (db) {
523                 NOTIFICATION_INFO("err [%d]", err);
524                 if (err == NOTIFICATION_ERROR_NONE)
525                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
526                 else
527                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
528
529
530                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
531                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
532
533         }
534
535         return err;
536 }
537
538 bool privilege_info_cb(const char *privilege_name, void *user_data)
539 {
540         bool *found = user_data;
541
542         if (privilege_name && strcmp(NOTIFICATION_PRIVILEGE, privilege_name) == 0) {
543                 *found = true;
544                 return false;
545         }
546
547         return true;
548 }
549
550 static bool _has_privilege(const char *package_id)
551 {
552         bool found = false;
553         int error_from_package_info = PACKAGE_MANAGER_ERROR_NONE;
554         package_info_h package_info = NULL;
555
556         error_from_package_info = package_info_create(package_id, &package_info);
557         if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
558                 NOTIFICATION_ERR("package_info_create failed [%d]", error_from_package_info);
559                 goto out;
560         }
561
562         error_from_package_info = package_info_foreach_privilege_info(package_info, privilege_info_cb, &found);
563
564         if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
565                 NOTIFICATION_ERR("package_info_foreach_privilege_info failed [%d]", error_from_package_info);
566                 goto out;
567         }
568
569 out:
570
571         if (package_info)
572                 package_info_destroy(package_info);
573
574         return found;
575 }
576
577 EXPORT_API int notification_setting_insert_package(const char *package_id)
578 {
579         int err = NOTIFICATION_ERROR_NONE;
580
581         if (_has_privilege(package_id) == true)
582                 err = _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id);
583
584         return err;
585 }
586
587 EXPORT_API int notification_setting_delete_package(const char *package_id)
588 {
589         return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id);
590 }
591
592 /* system setting --------------------------------*/
593
594 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
595 {
596         int ret = NOTIFICATION_ERROR_NONE;
597         if (system_setting == NULL) {
598                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
599                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
600         }
601         ret = notification_ipc_request_load_system_setting(system_setting);
602
603         return ret;
604 }
605
606 EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting)
607 {
608         int err = NOTIFICATION_ERROR_NONE;
609
610         if (system_setting == NULL) {
611                 NOTIFICATION_ERR("Invalid parameter\n");
612                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
613                 goto out;
614         }
615
616         err = notification_ipc_update_system_setting(system_setting);
617         if (err != NOTIFICATION_ERROR_NONE) {
618                 NOTIFICATION_ERR("notification_ipc_update_system_setting returns[%d]\n", err);
619                 goto out;
620         }
621
622 out:
623         return err;
624 }
625
626 EXPORT_API int notification_system_setting_free_system_setting(notification_system_setting_h system_setting)
627 {
628         int err = NOTIFICATION_ERROR_NONE;
629
630         if (system_setting == NULL) {
631                         NOTIFICATION_ERR("Invalid parameter\n");
632                         err = NOTIFICATION_ERROR_INVALID_PARAMETER;
633                         goto out;
634                 }
635
636         /* add codes to free all properties */
637
638         SAFE_FREE(system_setting);
639
640 out:
641
642         return err;
643 }
644
645 EXPORT_API int notification_system_setting_get_do_not_disturb(notification_system_setting_h system_setting, bool *value)
646 {
647         int err = NOTIFICATION_ERROR_NONE;
648
649         if (system_setting == NULL || value == NULL) {
650                 NOTIFICATION_ERR("Invalid parameter\n");
651                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
652                 goto out;
653         }
654
655         *value = system_setting->do_not_disturb;
656
657 out:
658
659         return err;
660 }
661
662 EXPORT_API int notification_system_setting_set_do_not_disturb(notification_system_setting_h system_setting, bool value)
663 {
664         int err = NOTIFICATION_ERROR_NONE;
665
666         if (system_setting == NULL) {
667                 NOTIFICATION_ERR("Invalid parameter\n");
668                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
669                 goto out;
670         }
671
672         system_setting->do_not_disturb = value;
673
674 out:
675
676         return err;
677 }
678
679 EXPORT_API int notification_system_setting_get_visibility_class(notification_system_setting_h system_setting, int *value)
680 {
681         int err = NOTIFICATION_ERROR_NONE;
682
683         if (system_setting == NULL || value == NULL) {
684                 NOTIFICATION_ERR("Invalid parameter\n");
685                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
686                 goto out;
687         }
688
689         *value = system_setting->visibility_class;
690
691 out:
692
693         return err;
694 }
695
696 EXPORT_API int notification_system_setting_set_visibility_class(notification_system_setting_h system_setting, int value)
697 {
698         int err = NOTIFICATION_ERROR_NONE;
699
700         if (system_setting == NULL) {
701                 NOTIFICATION_ERR("Invalid parameter\n");
702                 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
703                 goto out;
704         }
705
706         system_setting->visibility_class = value;
707
708 out:
709
710         return err;
711 }
712
713
714 EXPORT_API int notification_setting_db_update_system_setting(int do_not_disturb, int visibility_class)
715 {
716         int err = NOTIFICATION_ERROR_NONE;
717         int sqlret;
718         int field_index = 1;
719         sqlite3 *db = NULL;
720         sqlite3_stmt *db_statement = NULL;
721
722         sqlret = db_util_open(DBPATH, &db, 0);
723
724         if (sqlret != SQLITE_OK || db == NULL) {
725                 NOTIFICATION_ERR("db_util_open failed [%s][%d][%s]", DBPATH, sqlret, sqlite3_errmsg(db));
726                 err =  NOTIFICATION_ERROR_FROM_DB;
727                 goto return_close_db;
728         }
729
730         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
731
732         sqlret = sqlite3_prepare_v2(db, "UPDATE notification_system_setting SET do_not_disturb = ?, visibility_class = ?;", -1, &db_statement, NULL);
733
734         if (sqlret != SQLITE_OK) {
735                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlret, sqlite3_errmsg(db));
736                 err =  NOTIFICATION_ERROR_FROM_DB;
737                 goto return_close_db;
738         }
739
740         sqlite3_bind_int(db_statement, field_index++, do_not_disturb);
741         sqlite3_bind_int(db_statement, field_index++, visibility_class);
742
743         sqlret = sqlite3_step(db_statement);
744
745         if (sqlret != SQLITE_OK && sqlret != SQLITE_DONE) {
746                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlret, sqlite3_errmsg(db));
747                 err =  NOTIFICATION_ERROR_FROM_DB;
748                 goto return_close_db;
749         }
750
751         sqlret = sqlite3_changes(db);
752
753         if (sqlret == 0)
754                 NOTIFICATION_WARN("No changes on DB");
755
756
757 return_close_db:
758         if (db_statement)
759                 sqlite3_finalize(db_statement);
760
761
762         if (db) {
763                 if (err == NOTIFICATION_ERROR_NONE)
764                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
765                 else
766                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
767
768                 sqlret = db_util_close(db);
769         }
770
771         if (sqlret != SQLITE_OK)
772                 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
773
774         return err;
775 }
776
777 /* OLD IMPLEMENTATION ----------------------------*/
778 #define NOTIFICATION_SETTING_DB "notification_setting"
779 #define NOTIFICATION_SETTING_DB_PATH "/opt/usr/dbspace/.notification_parser.db"
780
781 struct _notification_setting_h {
782         char *appid;
783         char *notification;
784         char *sounds;
785         char *contents;
786         char *badge;
787         char *pkgid;
788 };
789
790 struct prop_table {
791         const char *property;
792         const char *column;
793         const char *default_value;
794 };
795
796 static struct prop_table g_prop_table[] = {
797         {
798                 .property = "OPT_NOTIFICATION",
799                 .column = "notification",
800                 .default_value = "ON",
801         },
802         {
803                 .property = "OPT_SOUNDS",
804                 .column = "sounds",
805                 .default_value = "ON",
806         },
807         {
808                 .property = "OPT_CONTENTS",
809                 .column = "contents",
810                 .default_value = "ON",
811         },
812         {
813                 .property = "OPT_BADGE",
814                 .column = "badge",
815                 .default_value = "ON",
816         },
817         {
818                 .property = NULL,
819                 .column = NULL,
820                 .default_value = NULL,
821         }
822 };
823
824 static const char *_get_prop_column(const char *property)
825 {
826         int i;
827
828         for (i = 0; g_prop_table[i].property; i++) {
829                 if (strcmp(g_prop_table[i].property, property))
830                         continue;
831
832                 return g_prop_table[i].column;
833         }
834
835         return NULL;
836 }
837
838 #ifdef TBD
839 static const char *_get_prop_default_value(const char *property)
840 {
841         int i;
842
843         for (i = 0; g_prop_table[i].property; i++) {
844                 if (strcmp(g_prop_table[i].property, property))
845                         continue;
846
847                 return g_prop_table[i].default_value;
848         }
849
850         return NULL;
851 }
852 #endif
853
854 static int _is_record_exist(const char *pkgname, sqlite3 *db)
855 {
856         sqlite3_stmt *stmt = NULL;
857         int count = 0;
858         int result = NOTIFICATION_ERROR_NONE;
859         char *sqlbuf = NULL;
860         int sqlret;
861
862         if (!pkgname)
863                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
864
865         if (!db)
866                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
867
868         sqlbuf = sqlite3_mprintf("SELECT count(*) FROM %s WHERE " \
869                         "appid = %Q",
870                         NOTIFICATION_SETTING_DB, pkgname);
871
872         if (!sqlbuf) {
873                 NOTIFICATION_ERR("fail to alloc sql query");
874                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
875         }
876
877         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
878         if (sqlret != SQLITE_OK) {
879                 NOTIFICATION_ERR("DB err [%s]", sqlite3_errmsg(db));
880                 NOTIFICATION_ERR("query[%s]", sqlbuf);
881                 result = NOTIFICATION_ERROR_FROM_DB;
882                 goto free_and_return;
883         }
884
885         sqlret = sqlite3_step(stmt);
886         if (sqlret == SQLITE_ROW)
887                 count = sqlite3_column_int(stmt, 0);
888         else
889                 count = 0;
890
891         if (count > 0)
892                 result = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
893         else
894                 result = NOTIFICATION_ERROR_NOT_EXIST_ID;
895
896 free_and_return:
897         if (sqlbuf)
898                 sqlite3_free(sqlbuf);
899
900         if (stmt)
901                 sqlite3_finalize(stmt);
902
903         return result;
904 }
905
906 EXPORT_API int notification_setting_db_set(const char *pkgname, const char *property, const char *value)
907 {
908         int ret = NOTIFICATION_ERROR_NONE;
909         int result = NOTIFICATION_ERROR_NONE;
910         sqlite3 *db = NULL;
911         char *sqlbuf = NULL;
912         int sqlret;
913         const char *column = NULL;
914
915         if (!pkgname || strlen(pkgname) == 0)
916                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
917
918         if (!property || strlen(property) == 0)
919                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
920
921         if (!value || strlen(value) == 0)
922                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
923
924         column = _get_prop_column(property);
925         if (!column)
926                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
927
928         sqlret = db_util_open(NOTIFICATION_SETTING_DB_PATH, &db, 0);
929         if (sqlret != SQLITE_OK || !db) {
930                 NOTIFICATION_ERR("fail to db_util_open - [%d]", sqlret);
931                 return NOTIFICATION_ERROR_FROM_DB;
932         }
933
934         ret = _is_record_exist(pkgname, db);
935         if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
936                 result = ret;
937                 goto return_close_db;
938         }
939
940         sqlbuf = sqlite3_mprintf("UPDATE %s SET %s = %Q " \
941                         "WHERE appid = %Q",
942                         NOTIFICATION_SETTING_DB, column, value, pkgname);
943         if (!sqlbuf) {
944                 NOTIFICATION_ERR("fail to alloc query");
945                 result = NOTIFICATION_ERROR_OUT_OF_MEMORY;
946                 goto return_close_db;
947         }
948
949         result = notification_db_exec(db, sqlbuf, NULL);
950
951 return_close_db:
952         if (sqlbuf)
953                 sqlite3_free(sqlbuf);
954
955         sqlret = db_util_close(db);
956         if (sqlret != SQLITE_OK)
957                 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
958
959         return result;
960 }
961
962 EXPORT_API int notification_setting_db_get(const char *pkgname, const char *property, char **value)
963 {
964         int ret = NOTIFICATION_ERROR_NONE;
965         int result = NOTIFICATION_ERROR_NONE;
966         sqlite3 *db = NULL;
967         char *sqlbuf = NULL;
968         sqlite3_stmt *stmt = NULL;
969         int sqlret;
970         const char *column = NULL;
971
972         if (!pkgname || strlen(pkgname) == 0)
973                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
974
975         if (!property || strlen(property) == 0)
976                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
977
978         if (!value)
979                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
980
981         column = _get_prop_column(property);
982         if (!column)
983                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
984
985         sqlret = db_util_open(NOTIFICATION_SETTING_DB_PATH, &db, 0);
986         if (sqlret != SQLITE_OK || !db) {
987                 NOTIFICATION_ERR("fail to db_util_open - [%d]", sqlret);
988                 return NOTIFICATION_ERROR_FROM_DB;
989         }
990
991         ret = _is_record_exist(pkgname, db);
992         if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
993                 result = ret;
994                 goto return_close_db;
995         }
996
997         sqlbuf = sqlite3_mprintf("SELECT %s FROM %s " \
998                         "WHERE appid = %Q",
999                         column, NOTIFICATION_SETTING_DB, pkgname);
1000         if (!sqlbuf) {
1001                 NOTIFICATION_ERR("fail to alloc query");
1002                 result = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1003                 goto return_close_db;
1004         }
1005
1006         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
1007         if (sqlret != SQLITE_OK) {
1008                 NOTIFICATION_ERR("fail to prepare %s - [%s]",
1009                                 sqlbuf, sqlite3_errmsg(db));
1010                 result = NOTIFICATION_ERROR_FROM_DB;
1011                 goto return_close_db;
1012         }
1013
1014         sqlret = sqlite3_step(stmt);
1015         if (sqlret == SQLITE_ROW) {
1016                 int get_bytes = sqlite3_column_bytes(stmt, 0);
1017                 char *get_data = (char *)calloc(get_bytes + 1, sizeof(char));
1018                 if (get_data != NULL) {
1019                         memcpy(get_data, sqlite3_column_text(stmt, 0),
1020                                         get_bytes * sizeof(char));
1021                         get_data[get_bytes] = '\0';
1022                         *value = get_data;
1023                 } else {
1024                         NOTIFICATION_ERR("fail to alloc query");
1025                         result = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1026                         goto return_close_db;
1027                 }
1028         }
1029
1030 return_close_db:
1031         if (sqlbuf)
1032                 sqlite3_free(sqlbuf);
1033
1034         if (stmt)
1035                 sqlite3_finalize(stmt);
1036
1037         sqlret = db_util_close(db);
1038         if (sqlret != SQLITE_OK)
1039                 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
1040
1041         return result;
1042 }
1043
1044 EXPORT_API int notification_setting_property_set(const char *pkgname, const char *property, const char *value)
1045 {
1046         int ret = 0;
1047
1048         if (!pkgname)
1049                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1050
1051         if (!property)
1052                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1053
1054         if (!value)
1055                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1056
1057         ret = notification_ipc_noti_setting_property_set(pkgname, property, value);
1058         if (ret != NOTIFICATION_ERROR_NONE)
1059                 return ret;
1060
1061         return NOTIFICATION_ERROR_NONE;
1062 }
1063
1064 EXPORT_API int notification_setting_property_get(const char *pkgname, const char *property, char **value)
1065 {
1066         int ret = 0;
1067
1068         if (!pkgname)
1069                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1070
1071         if (!property)
1072                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1073
1074         if (!value)
1075                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1076
1077         ret = notification_ipc_noti_setting_property_get(pkgname, property, value);
1078         if (ret != NOTIFICATION_ERROR_NONE)
1079                 return ret;
1080
1081         return NOTIFICATION_ERROR_NONE;
1082 }
1083