Move notification_get_text_input_max_length to internal
[platform/core/api/notification.git] / src / notification_setting.c
1 /*
2  * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <db-util.h>
21 #include <package_manager.h>
22 #include <pkgmgr-info.h>
23 #include <tizen_type.h>
24 #include <tzplatform_config.h>
25
26 #include <notification.h>
27 #include <notification_db.h>
28 #include <notification_list.h>
29 #include <notification_noti.h>
30 #include <notification_debug.h>
31 #include <notification_ipc.h>
32 #include <notification_private.h>
33 #include <notification_setting.h>
34 #include <notification_setting_internal.h>
35
36 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
37
38 typedef struct _noti_dnd_cb_info noti_dnd_cb_info_s;
39
40 typedef struct {
41         uid_t uid;
42         sqlite3 *db;
43 } setting_local_info;
44
45 struct _noti_dnd_cb_info {
46         dnd_changed_cb callback;
47         void *user_data;
48 };
49
50 static GHashTable *_noti_dnd_cb_hash = NULL;
51
52 EXPORT_API int notification_setting_get_setting_array_for_uid(notification_setting_h *setting_array, int *count, uid_t uid)
53 {
54         if (setting_array == NULL || count == NULL) {
55                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
56                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
57         }
58
59         return notification_ipc_request_get_setting_array(setting_array, count, uid);
60 }
61
62 EXPORT_API int notification_setting_get_setting_array(notification_setting_h *setting_array, int *count)
63 {
64         return notification_setting_get_setting_array_for_uid(setting_array, count, getuid());
65 }
66 EXPORT_API int notification_setting_get_setting_by_package_name_for_uid(const char *package_name, notification_setting_h *setting, uid_t uid)
67 {
68         if (package_name == NULL || setting == NULL) {
69                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
70                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
71         }
72
73         return notification_ipc_request_get_setting_by_package_name(package_name, setting, uid);
74 }
75
76 /* LCOV_EXCL_START */
77 EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting)
78 {
79         return notification_setting_get_setting_by_package_name_for_uid(package_name, setting, getuid());
80 }
81 /* LCOV_EXCL_STOP */
82
83 /* LCOV_EXCL_START */
84 EXPORT_API int notification_setting_get_setting(notification_setting_h *setting)
85 {
86         int ret;
87         char *package_name = NULL;
88
89         package_name = notification_get_pkgname_by_pid();
90
91         if (package_name == NULL)
92                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
93
94         ret = notification_setting_get_setting_by_package_name(package_name, setting);
95
96         free(package_name);
97
98         return ret;
99 }
100 /* LCOV_EXCL_STOP */
101
102 EXPORT_API int notification_setting_get_package_name(notification_setting_h setting, char **value)
103 {
104
105         if (setting == NULL || value == NULL) {
106                 NOTIFICATION_ERR("Invalid parameter");
107                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
108         }
109
110         if (setting->package_name == NULL) {
111                 NOTIFICATION_ERR("setting->package_name is null");
112                 return NOTIFICATION_ERROR_NOT_EXIST_ID;
113         }
114
115         *value = SAFE_STRDUP(setting->package_name);
116
117         return NOTIFICATION_ERROR_NONE;
118 }
119
120 EXPORT_API int notification_setting_set_package_name(notification_setting_h setting, char *value)
121 {
122
123         if (setting == NULL || value == NULL) {
124                 NOTIFICATION_ERR("Invalid parameter");
125                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
126         }
127
128         if (setting->package_name != NULL)
129                 free(setting->package_name);
130
131         setting->package_name = SAFE_STRDUP(value);
132
133         return NOTIFICATION_ERROR_NONE;
134 }
135
136 EXPORT_API int notification_setting_get_allow_to_notify(notification_setting_h setting, bool *value)
137 {
138         if (setting == NULL || value == NULL) {
139                 NOTIFICATION_ERR("Invalid parameter");
140                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
141         }
142
143         *value = setting->allow_to_notify;
144
145         return NOTIFICATION_ERROR_NONE;
146 }
147
148 EXPORT_API int notification_setting_set_allow_to_notify(notification_setting_h setting, bool value)
149 {
150         if (setting == NULL) {
151                 NOTIFICATION_ERR("Invalid parameter");
152                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
153         }
154
155         setting->allow_to_notify = value;
156
157         return NOTIFICATION_ERROR_NONE;
158 }
159
160 EXPORT_API int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value)
161 {
162         if (setting == NULL || value == NULL) {
163                 NOTIFICATION_ERR("Invalid parameter");
164                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
165         }
166
167         *value = setting->do_not_disturb_except;
168
169         return NOTIFICATION_ERROR_NONE;
170 }
171
172 EXPORT_API int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value)
173 {
174         if (setting == NULL) {
175                 NOTIFICATION_ERR("Invalid parameter");
176                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
177         }
178
179         setting->do_not_disturb_except = value;
180
181         return NOTIFICATION_ERROR_NONE;
182 }
183
184 EXPORT_API int notification_setting_get_visibility_class(notification_setting_h setting, int *value)
185 {
186         if (setting == NULL || value == NULL) {
187                 NOTIFICATION_ERR("Invalid parameter");
188                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
189         }
190
191         *value = setting->visibility_class;
192
193         return NOTIFICATION_ERROR_NONE;
194 }
195
196 EXPORT_API int notification_setting_set_visibility_class(notification_setting_h setting, int value)
197 {
198         if (setting == NULL) {
199                 NOTIFICATION_ERR("Invalid parameter");
200                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
201         }
202
203         setting->visibility_class = value;
204
205         return NOTIFICATION_ERROR_NONE;
206 }
207
208 EXPORT_API int notification_setting_get_pop_up_notification(notification_setting_h setting, bool *value)
209 {
210         if (setting == NULL || value == NULL) {
211                 NOTIFICATION_ERR("Invalid parameter");
212                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
213         }
214
215         *value = setting->pop_up_notification;
216         return NOTIFICATION_ERROR_NONE;
217 }
218
219 EXPORT_API int notification_setting_set_pop_up_notification(notification_setting_h setting, bool value)
220 {
221         if (setting == NULL) {
222                 NOTIFICATION_ERR("Invalid parameter");
223                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
224         }
225
226         setting->pop_up_notification = value;
227         return NOTIFICATION_ERROR_NONE;
228 }
229
230 EXPORT_API int notification_setting_get_lock_screen_content(notification_setting_h setting, lock_screen_content_level_e *level)
231 {
232         if (setting == NULL || level == NULL) {
233                 NOTIFICATION_ERR("Invalid parameter");
234                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
235         }
236
237         *level = setting->lock_screen_content_level;
238         return NOTIFICATION_ERROR_NONE;
239 }
240
241 EXPORT_API int notification_setting_set_lock_screen_content(notification_setting_h setting, lock_screen_content_level_e level)
242 {
243         if (setting == NULL) {
244                 NOTIFICATION_ERR("Invalid parameter");
245                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
246         }
247
248         setting->lock_screen_content_level = level;
249         return NOTIFICATION_ERROR_NONE;
250 }
251
252 EXPORT_API int notification_setting_update_setting_for_uid(notification_setting_h setting, uid_t uid)
253 {
254         if (setting == NULL) {
255                 NOTIFICATION_ERR("Invalid parameter");
256                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
257         }
258
259         return notification_ipc_update_setting(setting, uid);
260 }
261
262 EXPORT_API int notification_setting_update_setting(notification_setting_h setting)
263 {
264         return notification_setting_update_setting_for_uid(setting, getuid());
265 }
266
267 EXPORT_API int notification_setting_free_notification(notification_setting_h setting)
268 {
269         if (setting == NULL) {
270                 NOTIFICATION_ERR("Invalid parameter");
271                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
272         }
273
274         SAFE_FREE(setting->package_name);
275
276         /* add codes to free all properties */
277
278         SAFE_FREE(setting);
279
280         return NOTIFICATION_ERROR_NONE;
281 }
282
283 static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name, uid_t uid)
284 {
285         sqlite3_stmt *db_statement = NULL;
286         int sqlite3_ret = SQLITE_OK;
287         bool err = true;
288         int field_index = 1;
289
290         sqlite3_ret = sqlite3_prepare_v2(db, "SELECT package_name FROM notification_setting WHERE uid = ? AND package_name = ?", -1, &db_statement, NULL);
291
292         if (sqlite3_ret != SQLITE_OK) {
293                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
294                 err = false;
295                 goto out;
296         }
297
298         sqlite3_bind_int(db_statement, field_index++, uid);
299         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
300
301         sqlite3_ret = sqlite3_step(db_statement);
302
303         if (sqlite3_ret == SQLITE_DONE) {
304                 NOTIFICATION_INFO("no matched package_name found[%s][%d]", package_name, sqlite3_ret);
305                 err = false;
306                 goto out;
307         }
308
309         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
310                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
311                 err = false;
312                 goto out;
313         }
314 out:
315         if (db_statement)
316                 sqlite3_finalize(db_statement);
317
318         return err;
319 }
320
321 static int foreach_package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
322 {
323         setting_local_info *info = (setting_local_info *)user_data;
324         sqlite3 *db = info->db;
325         sqlite3_stmt *db_statement = NULL;
326         char *package_name = NULL;
327         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
328         int sqlite3_ret = SQLITE_OK;
329         int field_index = 1;
330         int err = true;
331
332         if ((pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &package_name)) != PACKAGE_MANAGER_ERROR_NONE) {
333                 NOTIFICATION_ERR("package_info_get_package failed [%d]", pkgmgr_ret);
334                 err = false;
335                 goto out;
336         }
337
338         if (_is_package_in_setting_table(db, package_name, info->uid) == true) {
339                 NOTIFICATION_INFO("uid %d [%s] is exist", info->uid, package_name);
340                 goto out;
341         }
342
343         NOTIFICATION_INFO("uid %d [%s] will be inserted", info->uid, package_name);
344         sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
345
346         if (sqlite3_ret != SQLITE_OK) {
347                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
348                 err = false;
349                 goto out;
350         }
351
352         sqlite3_bind_int(db_statement, field_index++, info->uid);
353         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
354
355         sqlite3_ret = sqlite3_step(db_statement);
356
357         NOTIFICATION_INFO("sqlite3_step returns[%d]", sqlite3_ret);
358
359         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
360                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
361                 err = false;
362         }
363
364 out:
365         if (db_statement)
366                 sqlite3_finalize(db_statement);
367
368         return err;
369 }
370
371 EXPORT_API int notification_setting_refresh_setting_table(uid_t uid)
372 {
373         int err = NOTIFICATION_ERROR_NONE;
374         sqlite3 *db = NULL;
375         int sqlite3_ret = SQLITE_OK;
376         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
377         pkgmgrinfo_pkginfo_filter_h filter;
378         setting_local_info info;
379
380         NOTIFICATION_INFO("refresh setting table [%d]", uid);
381         sqlite3_ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);
382         if (sqlite3_ret != SQLITE_OK || db == NULL) {
383                 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
384                 err = NOTIFICATION_ERROR_FROM_DB;
385                 goto out;
386         }
387
388         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
389
390         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
391         if (pkgmgr_ret != PMINFO_R_OK) {
392                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
393                 err = NOTIFICATION_ERROR_FROM_DB;
394                 goto out;
395         }
396
397         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(filter, PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, NOTIFICATION_PRIVILEGE);
398         if (pkgmgr_ret != PMINFO_R_OK) {
399                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
400                 err = NOTIFICATION_ERROR_FROM_DB;
401                 goto out;
402         }
403
404         info.db = db;
405         info.uid = uid;
406         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, foreach_package_info_callback, &info, uid);
407         if (pkgmgr_ret != PMINFO_R_OK) {
408                 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
409                 err = NOTIFICATION_ERROR_FROM_DB;
410                 goto out;
411         }
412
413         pkgmgrinfo_pkginfo_filter_destroy(filter);
414
415 out:
416
417         if (db) {
418                 if (err == NOTIFICATION_ERROR_NONE)
419                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
420                 else
421                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
422
423                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
424                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
425         }
426
427         return err;
428 }
429
430 typedef enum {
431         OPERATION_TYPE_INSERT_RECORD = 0,
432         OPERATION_TYPE_DELETE_RECORD = 1,
433 } notification_setting_operation_type;
434
435 static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name, uid_t uid)
436 {
437         sqlite3 *db = NULL;
438         sqlite3_stmt *db_statement = NULL;
439         int sqlite3_ret = SQLITE_OK;
440         int field_index = 1;
441         bool is_package_in_setting_table = false;
442         int err = NOTIFICATION_ERROR_NONE;
443
444         sqlite3_ret = db_util_open(DBPATH, &db, 0);
445
446         if (sqlite3_ret != SQLITE_OK || db == NULL) {
447                 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
448                 err = NOTIFICATION_ERROR_FROM_DB;
449                 goto out;
450         }
451
452         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
453
454         is_package_in_setting_table = _is_package_in_setting_table(db, package_name, uid);
455
456         switch (operation_type) {
457         case OPERATION_TYPE_INSERT_RECORD:
458                 if (is_package_in_setting_table == true) {
459                         NOTIFICATION_INFO("[%s] is already exist", package_name);
460                         goto out;
461                 }
462                 NOTIFICATION_INFO("[%s] will be inserted", package_name);
463                 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
464                 break;
465
466         case OPERATION_TYPE_DELETE_RECORD:
467                 if (is_package_in_setting_table == false) {
468                         NOTIFICATION_INFO("[%s] is not exist", package_name);
469                         goto out;
470                 }
471                 NOTIFICATION_INFO("[%s] will be removed", package_name);
472                 sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE uid = ? AND package_name = ? ", -1, &db_statement, NULL);
473                 break;
474         default:
475                 break;
476         }
477
478         if (sqlite3_ret != SQLITE_OK) {
479                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
480                 err = NOTIFICATION_ERROR_FROM_DB;
481                 goto out;
482         }
483
484         sqlite3_bind_int(db_statement, field_index++, uid);
485         sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
486
487         sqlite3_ret = sqlite3_step(db_statement);
488
489         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
490                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
491                 err = NOTIFICATION_ERROR_FROM_DB;
492         }
493
494 out:
495         if (db_statement)
496                 sqlite3_finalize(db_statement);
497
498         if (db) {
499                 NOTIFICATION_INFO("err [%d]", err);
500                 if (err == NOTIFICATION_ERROR_NONE)
501                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
502                 else
503                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
504
505
506                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
507                         NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
508
509         }
510
511         return err;
512 }
513
514 EXPORT_API int notification_setting_insert_package_for_uid(const char *package_id, uid_t uid)
515 {
516         return _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id, uid);
517 }
518
519 EXPORT_API int notification_setting_delete_package_for_uid(const char *package_id, uid_t uid)
520 {
521         return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id, uid);
522 }
523
524 EXPORT_API int notification_system_setting_load_system_setting_for_uid(notification_system_setting_h *system_setting, uid_t uid)
525 {
526         if (system_setting == NULL) {
527                 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
528                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
529         }
530
531         return notification_ipc_request_load_system_setting(system_setting, uid);
532 }
533
534 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
535 {
536         return notification_system_setting_load_system_setting_for_uid(system_setting, getuid());
537 }
538
539 EXPORT_API int notification_system_setting_update_system_setting_for_uid(notification_system_setting_h system_setting, uid_t uid)
540 {
541         if (system_setting == NULL) {
542                 NOTIFICATION_ERR("Invalid parameter");
543                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
544         }
545
546         return notification_ipc_update_system_setting(system_setting, uid);
547 }
548
549 EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting)
550 {
551         return notification_system_setting_update_system_setting_for_uid(system_setting, getuid());
552 }
553
554 EXPORT_API int notification_system_setting_free_system_setting(notification_system_setting_h system_setting)
555 {
556         if (system_setting == NULL) {
557                 NOTIFICATION_ERR("Invalid parameter");
558                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
559         }
560
561         /* add codes to free all properties */
562
563         if (system_setting->dnd_allow_exceptions != NULL)
564                 g_list_free(system_setting->dnd_allow_exceptions);
565
566         SAFE_FREE(system_setting);
567
568         return NOTIFICATION_ERROR_NONE;
569 }
570
571 EXPORT_API int notification_system_setting_get_do_not_disturb(notification_system_setting_h system_setting, bool *value)
572 {
573         if (system_setting == NULL || value == NULL) {
574                 NOTIFICATION_ERR("Invalid parameter");
575                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
576         }
577
578         *value = system_setting->do_not_disturb;
579
580         return NOTIFICATION_ERROR_NONE;
581 }
582
583 EXPORT_API int notification_system_setting_set_do_not_disturb(notification_system_setting_h system_setting, bool value)
584 {
585         if (system_setting == NULL) {
586                 NOTIFICATION_ERR("Invalid parameter");
587                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
588         }
589
590         system_setting->do_not_disturb = value;
591
592         return NOTIFICATION_ERROR_NONE;
593 }
594
595 EXPORT_API int notification_system_setting_get_visibility_class(notification_system_setting_h system_setting, int *value)
596 {
597         if (system_setting == NULL || value == NULL) {
598                 NOTIFICATION_ERR("Invalid parameter");
599                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
600         }
601
602         *value = system_setting->visibility_class;
603
604         return NOTIFICATION_ERROR_NONE;
605 }
606
607 EXPORT_API int notification_system_setting_set_visibility_class(notification_system_setting_h system_setting, int value)
608 {
609         if (system_setting == NULL) {
610                 NOTIFICATION_ERR("Invalid parameter");
611                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
612         }
613
614         system_setting->visibility_class = value;
615
616         return NOTIFICATION_ERROR_NONE;
617 }
618
619 EXPORT_API int notification_system_setting_dnd_schedule_get_enabled(notification_system_setting_h system_setting, bool *enabled)
620 {
621         if (system_setting == NULL || enabled == NULL) {
622                 NOTIFICATION_ERR("Invalid parameter");
623                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
624         }
625
626         *enabled = system_setting->dnd_schedule_enabled;
627
628         return NOTIFICATION_ERROR_NONE;
629 }
630
631 EXPORT_API int notification_system_setting_dnd_schedule_set_enabled(notification_system_setting_h system_setting, bool enabled)
632 {
633         if (system_setting == NULL) {
634                 NOTIFICATION_ERR("Invalid parameter");
635                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
636         }
637
638         system_setting->dnd_schedule_enabled = enabled;
639
640         return NOTIFICATION_ERROR_NONE;
641 }
642
643 EXPORT_API int notification_system_setting_dnd_schedule_get_day(notification_system_setting_h system_setting, int *day)
644 {
645         if (system_setting == NULL || day == NULL) {
646                 NOTIFICATION_ERR("Invalid parameter");
647                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
648         }
649
650         *day = system_setting->dnd_schedule_day;
651
652         return NOTIFICATION_ERROR_NONE;
653 }
654
655 EXPORT_API int notification_system_setting_dnd_schedule_set_day(notification_system_setting_h system_setting, int day)
656 {
657         if (system_setting == NULL) {
658                 NOTIFICATION_ERR("Invalid parameter");
659                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
660         }
661
662         system_setting->dnd_schedule_day = day;
663
664         return NOTIFICATION_ERROR_NONE;
665 }
666
667 EXPORT_API int notification_system_setting_dnd_schedule_get_start_time(notification_system_setting_h system_setting, int *hour, int *min)
668 {
669         if (system_setting == NULL || hour == NULL || min == NULL) {
670                 NOTIFICATION_ERR("Invalid parameter");
671                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
672         }
673
674         *hour = system_setting->dnd_start_hour;
675         *min = system_setting->dnd_start_min;
676
677         return NOTIFICATION_ERROR_NONE;
678 }
679
680 EXPORT_API int notification_system_setting_dnd_schedule_set_start_time(notification_system_setting_h system_setting, int hour, int min)
681 {
682         if (system_setting == NULL) {
683                 NOTIFICATION_ERR("Invalid parameter");
684                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
685         }
686
687         system_setting->dnd_start_hour = hour;
688         system_setting->dnd_start_min = min;
689
690         return NOTIFICATION_ERROR_NONE;
691 }
692
693 EXPORT_API int notification_system_setting_dnd_schedule_get_end_time(notification_system_setting_h system_setting, int *hour, int *min)
694 {
695         if (system_setting == NULL || hour == NULL || min == NULL) {
696                 NOTIFICATION_ERR("Invalid parameter");
697                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
698         }
699
700         *hour = system_setting->dnd_end_hour;
701         *min = system_setting->dnd_end_min;
702
703         return NOTIFICATION_ERROR_NONE;
704 }
705
706 EXPORT_API int notification_system_setting_dnd_schedule_set_end_time(notification_system_setting_h system_setting, int hour, int min)
707 {
708         if (system_setting == NULL) {
709                 NOTIFICATION_ERR("Invalid parameter");
710                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
711         }
712
713         system_setting->dnd_end_hour = hour;
714         system_setting->dnd_end_min = min;
715
716         return NOTIFICATION_ERROR_NONE;
717 }
718
719 EXPORT_API int notification_system_setting_get_lock_screen_content(notification_system_setting_h system_setting, lock_screen_content_level_e *level)
720 {
721         if (system_setting == NULL || level == NULL) {
722                 NOTIFICATION_ERR("Invalid parameter");
723                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
724         }
725
726         *level = system_setting->lock_screen_content_level;
727
728         return NOTIFICATION_ERROR_NONE;
729 }
730
731 EXPORT_API int notification_system_setting_set_lock_screen_content(notification_system_setting_h system_setting, lock_screen_content_level_e level)
732 {
733         if (system_setting == NULL) {
734                 NOTIFICATION_ERR("Invalid parameter");
735                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
736         }
737
738         system_setting->lock_screen_content_level = level;
739
740         return NOTIFICATION_ERROR_NONE;
741 }
742
743 static gint _dnd_allow_exception_compare(gconstpointer a, gconstpointer b)
744 {
745         dnd_allow_exception_h dnd_allow_exception_data_a;
746
747         if (a == NULL)
748                 return -1;
749
750         dnd_allow_exception_data_a = (dnd_allow_exception_h)a;
751
752         if (dnd_allow_exception_data_a->type == (int)b)
753                 return 0;
754
755         return -1;
756 }
757
758 EXPORT_API int notification_system_setting_get_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int *value)
759 {
760         dnd_allow_exception_h dnd_allow_exception_data;
761         GList *list;
762
763         if (system_setting == NULL || value == NULL) {
764                 NOTIFICATION_ERR("Invalid parameter");
765                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
766         }
767
768         list = g_list_find_custom(system_setting->dnd_allow_exceptions, (gconstpointer)type, _dnd_allow_exception_compare);
769         if (list) {
770                 dnd_allow_exception_data = (dnd_allow_exception_h)list->data;
771                 *value = dnd_allow_exception_data->value;
772         } else {
773                 NOTIFICATION_ERR("Invalid parameter - type");
774                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
775         }
776
777         return NOTIFICATION_ERROR_NONE;
778 }
779
780 EXPORT_API int notification_system_setting_set_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int value)
781 {
782         dnd_allow_exception_h dnd_allow_exception_data;
783         GList *list;
784
785         if (system_setting == NULL) {
786                 NOTIFICATION_ERR("Invalid parameter");
787                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
788         }
789
790         list = g_list_first(system_setting->dnd_allow_exceptions);
791
792         for (; list != NULL; list = list->next) {
793                 dnd_allow_exception_data = (dnd_allow_exception_h)list->data;
794                 if (dnd_allow_exception_data->type == type) {
795                         dnd_allow_exception_data->value = value;
796                         return NOTIFICATION_ERROR_NONE;
797                 }
798         }
799
800         dnd_allow_exception_data = (dnd_allow_exception_h)malloc(sizeof(struct notification_system_setting_dnd_allow_exception));
801         if (dnd_allow_exception_data == NULL)
802                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
803
804         dnd_allow_exception_data->type = type;
805         dnd_allow_exception_data->value = value;
806
807         system_setting->dnd_allow_exceptions = g_list_append(system_setting->dnd_allow_exceptions, dnd_allow_exception_data);
808
809         return NOTIFICATION_ERROR_NONE;
810 }
811
812 static gint _noti_dnd_cb_compare(gconstpointer a, gconstpointer b)
813 {
814         noti_dnd_cb_info_s *info = NULL;
815
816         if (a == NULL)
817                 return -1;
818
819         info = (noti_dnd_cb_info_s *)a;
820         if (info->callback == b)
821                 return 0;
822
823         return 1;
824 }
825
826 void notification_call_dnd_changed_cb_for_uid(int do_not_disturb, uid_t uid)
827 {
828         GList *noti_dnd_cb_list = NULL;
829         noti_dnd_cb_info_s *dnd_data = NULL;
830
831         if (_noti_dnd_cb_hash == NULL)
832                 return;
833
834         noti_dnd_cb_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid));
835         if (noti_dnd_cb_list == NULL) {
836                 NOTIFICATION_ERR("Invalide data");
837                 return;
838         }
839
840         noti_dnd_cb_list = g_list_first(noti_dnd_cb_list);
841
842         for (; noti_dnd_cb_list != NULL; noti_dnd_cb_list = noti_dnd_cb_list->next) {
843                 dnd_data = noti_dnd_cb_list->data;
844
845                 if (dnd_data != NULL && dnd_data->callback != NULL)
846                         dnd_data->callback(dnd_data->user_data, do_not_disturb);
847         }
848 }
849
850 EXPORT_API int notification_register_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, void *user_data, uid_t uid)
851 {
852         GList *noti_dnd_list = NULL;
853         GList *noti_dnd_found_list = NULL;
854         noti_dnd_cb_info_s *dnd_data = NULL;
855
856         if (callback == NULL)
857                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
858
859         if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE) {
860                 NOTIFICATION_ERR("notification_ipc_monitor_init error");
861                 return NOTIFICATION_ERROR_IO_ERROR;
862         }
863         if (_noti_dnd_cb_hash == NULL)
864                 _noti_dnd_cb_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
865
866         dnd_data = (noti_dnd_cb_info_s *)malloc(sizeof(noti_dnd_cb_info_s));
867         if (dnd_data == NULL)
868                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
869
870         dnd_data->callback = callback;
871         dnd_data->user_data = user_data;
872
873         noti_dnd_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid));
874
875         if (noti_dnd_list == NULL) {
876                 noti_dnd_list = g_list_append(noti_dnd_list, dnd_data);
877                 g_hash_table_insert(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid), noti_dnd_list);
878         } else {
879                 noti_dnd_found_list = g_list_find_custom(noti_dnd_list, (gconstpointer)callback,
880                                                          _noti_dnd_cb_compare);
881                 if (noti_dnd_found_list) {
882                         NOTIFICATION_ERR("Already existing callback");
883                         free(dnd_data);
884                         return NOTIFICATION_ERROR_INVALID_PARAMETER;
885                 } else {
886                         noti_dnd_list = g_list_append(noti_dnd_list, dnd_data);
887                 }
888         }
889
890         return NOTIFICATION_ERROR_NONE;
891 }
892
893 EXPORT_API int notification_register_system_setting_dnd_changed_cb(dnd_changed_cb callback, void *user_data)
894 {
895         return notification_register_system_setting_dnd_changed_cb_for_uid(callback, user_data, getuid());
896 }
897
898 EXPORT_API int notification_unregister_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, uid_t uid)
899 {
900         GList *noti_dnd_cb_list = NULL;
901         GList *noti_dnd_del_list = NULL;
902         noti_dnd_cb_info_s *dnd_data = NULL;
903
904         if (callback == NULL)
905                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
906
907         if (_noti_dnd_cb_hash == NULL)
908                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
909
910         noti_dnd_cb_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid));
911
912         if (noti_dnd_cb_list == NULL)
913                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
914
915         noti_dnd_del_list = g_list_find_custom(noti_dnd_cb_list, (gconstpointer)callback,
916                                                _noti_dnd_cb_compare);
917
918         if (noti_dnd_del_list) {
919                 dnd_data = g_list_nth_data(noti_dnd_del_list, 0);
920                 noti_dnd_cb_list = g_list_delete_link(noti_dnd_cb_list, noti_dnd_del_list);
921                 free(dnd_data);
922         } else {
923                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
924         }
925
926         if (noti_dnd_cb_list == NULL) {
927                 g_hash_table_steal(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid));
928         } else {
929                 noti_dnd_cb_list = g_list_first(noti_dnd_cb_list);
930                 g_hash_table_replace(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid), noti_dnd_cb_list);
931         }
932
933         if (g_hash_table_size(_noti_dnd_cb_hash) == 0)
934                 notification_ipc_monitor_fini();
935
936         return NOTIFICATION_ERROR_NONE;
937 }
938
939 EXPORT_API int notification_unregister_system_setting_dnd_changed_cb(dnd_changed_cb callback)
940 {
941         return notification_unregister_system_setting_dnd_changed_cb_for_uid(callback, getuid());
942 }
943
944 static bool _is_uid_in_system_setting_table(sqlite3 *db, uid_t uid)
945 {
946         bool err = true;
947         sqlite3_stmt *db_statement = NULL;
948         int sqlite3_ret = SQLITE_OK;
949         int field_index = 1;
950
951         sqlite3_ret = sqlite3_prepare_v2(db, "SELECT uid FROM notification_system_setting WHERE uid = ?", -1, &db_statement, NULL);
952         if (sqlite3_ret != SQLITE_OK) {
953                 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
954                 err = false;
955                 goto out;
956         }
957
958         sqlite3_bind_int(db_statement, field_index++, uid);
959
960         sqlite3_ret = sqlite3_step(db_statement);
961         if (sqlite3_ret == SQLITE_DONE) {
962                 NOTIFICATION_INFO("no matched uid found[%d][%d]", uid, sqlite3_ret);
963                 err = false;
964                 goto out;
965         }
966
967         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
968                 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
969                 err = false;
970                 goto out;
971         }
972
973 out:
974         if (db_statement)
975                 sqlite3_finalize(db_statement);
976
977         return err;
978 }
979
980 EXPORT_API int notification_system_setting_init_system_setting_table(uid_t uid)
981 {
982         int err = NOTIFICATION_ERROR_NONE;
983         int sqlite3_ret = SQLITE_OK;
984         int field_index = 1;
985         sqlite3 *db = NULL;
986         sqlite3_stmt *db_statement = NULL;
987
988         NOTIFICATION_INFO("init system setting table [%d]", uid);
989         db = notification_db_open(DBPATH);
990         if (db == NULL)
991                 return get_last_result();
992
993         /* if notification system setting don't init. */
994         if (_is_uid_in_system_setting_table(db, uid) == true) {
995                 NOTIFICATION_DBG("Notification system setting table is already initialized.");
996         } else {
997                 NOTIFICATION_DBG("Notification system setting table is not initialized yet");
998                 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_system_setting (uid) VALUES (?) ", -1, &db_statement, NULL);
999                 if (sqlite3_ret != SQLITE_OK) {
1000                         NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
1001                         err = NOTIFICATION_ERROR_FROM_DB;
1002                         goto out;
1003                 }
1004
1005                 sqlite3_bind_int(db_statement, field_index++, uid);
1006
1007                 sqlite3_ret = sqlite3_step(db_statement);
1008                 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
1009                         NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
1010                         err = NOTIFICATION_ERROR_FROM_DB;
1011                         goto out;
1012                 }
1013         }
1014
1015         NOTIFICATION_DBG("Notification system setting tables initialization is success.");
1016
1017 out:
1018         if (db) {
1019                 if (err == NOTIFICATION_ERROR_NONE)
1020                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
1021                 else
1022                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
1023                 notification_db_close(&db);
1024         }
1025         if (db_statement)
1026                 sqlite3_finalize(db_statement);
1027
1028         return err;
1029 }