2 * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <package_manager.h>
22 #include <pkgmgr-info.h>
23 #include <tizen_type.h>
24 #include <tzplatform_config.h>
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>
36 #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification"
43 EXPORT_API int notification_setting_get_setting_array_for_uid(notification_setting_h *setting_array, int *count, uid_t uid)
45 int ret = NOTIFICATION_ERROR_NONE;
46 if (setting_array == NULL || count == NULL) {
47 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
48 return NOTIFICATION_ERROR_INVALID_PARAMETER;
50 ret = notification_ipc_request_get_setting_array(setting_array, count, uid);
54 EXPORT_API int notification_setting_get_setting_array(notification_setting_h *setting_array, int *count)
56 return notification_setting_get_setting_array_for_uid(setting_array, count, getuid());
59 EXPORT_API int notification_setting_get_setting_by_package_name_for_uid(const char *package_name, notification_setting_h *setting, uid_t uid)
61 int ret = NOTIFICATION_ERROR_NONE;
62 if (package_name == NULL || setting == NULL) {
63 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
64 return NOTIFICATION_ERROR_INVALID_PARAMETER;
66 ret = notification_ipc_request_get_setting_by_package_name(package_name, setting, uid);
70 EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting)
72 return notification_setting_get_setting_by_package_name_for_uid(package_name, setting, getuid());
75 EXPORT_API int notification_setting_get_setting(notification_setting_h *setting)
78 char *package_name = NULL;
80 package_name = notification_get_pkgname_by_pid();
82 if (package_name == NULL)
83 return NOTIFICATION_ERROR_NOT_EXIST_ID;
85 ret = notification_setting_get_setting_by_package_name(package_name, setting);
92 EXPORT_API int notification_setting_get_package_name(notification_setting_h setting, char **value)
94 int err = NOTIFICATION_ERROR_NONE;
96 if (setting == NULL || value == NULL) {
97 NOTIFICATION_ERR("Invalid parameter\n");
98 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
102 if (setting->package_name == NULL) {
103 NOTIFICATION_ERR("setting->package_name is null\n");
104 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
108 *value = SAFE_STRDUP(setting->package_name);
115 EXPORT_API int notification_setting_set_package_name(notification_setting_h setting, char *value)
117 int err = NOTIFICATION_ERROR_NONE;
119 if (setting == NULL || value == NULL) {
120 NOTIFICATION_ERR("Invalid parameter\n");
121 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
125 if (setting->package_name != NULL)
126 free(setting->package_name);
128 setting->package_name = SAFE_STRDUP(value);
135 EXPORT_API int notification_setting_get_allow_to_notify(notification_setting_h setting, bool *value)
137 int err = NOTIFICATION_ERROR_NONE;
139 if (setting == NULL || value == NULL) {
140 NOTIFICATION_ERR("Invalid parameter\n");
141 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
145 *value = setting->allow_to_notify;
152 EXPORT_API int notification_setting_set_allow_to_notify(notification_setting_h setting, bool value)
154 int err = NOTIFICATION_ERROR_NONE;
156 if (setting == NULL) {
157 NOTIFICATION_ERR("Invalid parameter\n");
158 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
162 setting->allow_to_notify = value;
169 EXPORT_API int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value)
171 int err = NOTIFICATION_ERROR_NONE;
173 if (setting == NULL || value == NULL) {
174 NOTIFICATION_ERR("Invalid parameter\n");
175 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
179 *value = setting->do_not_disturb_except;
186 EXPORT_API int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value)
188 int err = NOTIFICATION_ERROR_NONE;
190 if (setting == NULL) {
191 NOTIFICATION_ERR("Invalid parameter\n");
192 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
196 setting->do_not_disturb_except = value;
203 EXPORT_API int notification_setting_get_visibility_class(notification_setting_h setting, int *value)
205 int err = NOTIFICATION_ERROR_NONE;
207 if (setting == NULL || value == NULL) {
208 NOTIFICATION_ERR("Invalid parameter\n");
209 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
213 *value = setting->visibility_class;
220 EXPORT_API int notification_setting_set_visibility_class(notification_setting_h setting, int value)
222 int err = NOTIFICATION_ERROR_NONE;
224 if (setting == NULL) {
225 NOTIFICATION_ERR("Invalid parameter\n");
226 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
230 setting->visibility_class = value;
237 EXPORT_API int notification_setting_update_setting_for_uid(notification_setting_h setting, uid_t uid)
239 int err = NOTIFICATION_ERROR_NONE;
241 if (setting == NULL) {
242 NOTIFICATION_ERR("Invalid parameter\n");
243 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
247 err = notification_ipc_update_setting(setting, uid);
248 if (err != NOTIFICATION_ERROR_NONE) {
249 NOTIFICATION_ERR("notification_setting_update_setting returns[%d]\n", err);
257 EXPORT_API int notification_setting_update_setting(notification_setting_h setting)
259 return notification_setting_update_setting_for_uid(setting, getuid());
262 EXPORT_API int notification_setting_free_notification(notification_setting_h setting)
264 int err = NOTIFICATION_ERROR_NONE;
266 if (setting == NULL) {
267 NOTIFICATION_ERR("Invalid parameter\n");
268 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
272 SAFE_FREE(setting->package_name);
274 /* add codes to free all properties */
282 EXPORT_API int notification_setting_db_update(const char *package_name, int allow_to_notify, int do_not_disturb_except, int visibility_class, uid_t uid)
284 int err = NOTIFICATION_ERROR_NONE;
289 if (package_name == NULL || strlen(package_name) == 0)
290 return NOTIFICATION_ERROR_INVALID_PARAMETER;
292 sqlret = db_util_open(DBPATH, &db, 0);
293 if (sqlret != SQLITE_OK || db == NULL) {
294 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret);
295 return NOTIFICATION_ERROR_FROM_DB;
298 sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_notify = %d, do_not_disturb_except = %d, visibility_class = %d " \
299 "WHERE package_name = %Q AND uid = %d",
300 NOTIFICATION_SETTING_DB_TABLE, allow_to_notify, do_not_disturb_except, visibility_class, package_name, uid);
302 NOTIFICATION_ERR("fail to alloc query");
303 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
304 goto return_close_db;
307 err = notification_db_exec(db, sqlbuf, NULL);
311 sqlite3_free(sqlbuf);
313 sqlret = db_util_close(db);
314 if (sqlret != SQLITE_OK)
315 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
320 static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name, uid_t uid)
322 sqlite3_stmt *db_statement = NULL;
323 int sqlite3_ret = SQLITE_OK;
327 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT package_name FROM notification_setting WHERE uid = ? AND package_name = ?", -1, &db_statement, NULL);
329 if (sqlite3_ret != SQLITE_OK) {
330 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
335 sqlite3_bind_int(db_statement, field_index++, uid);
336 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
338 sqlite3_ret = sqlite3_step(db_statement);
340 if (sqlite3_ret == SQLITE_DONE) {
341 NOTIFICATION_INFO("no matched package_name found[%s][%d]", package_name, sqlite3_ret);
346 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
347 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
353 sqlite3_finalize(db_statement);
358 static int foreach_package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
360 setting_local_info *info = (setting_local_info *)user_data;
361 sqlite3 *db = info->db;
362 sqlite3_stmt *db_statement = NULL;
363 char *package_name = NULL;
364 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
365 int sqlite3_ret = SQLITE_OK;
369 if ((pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &package_name)) != PACKAGE_MANAGER_ERROR_NONE) {
370 NOTIFICATION_ERR("package_info_get_package failed [%d]", pkgmgr_ret);
375 if (_is_package_in_setting_table(db, package_name, info->uid) == true) {
376 NOTIFICATION_INFO("uid %d [%s] is exist", info->uid, package_name);
380 NOTIFICATION_INFO("uid %d [%s] will be inserted", info->uid, package_name);
381 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
383 if (sqlite3_ret != SQLITE_OK) {
384 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
389 sqlite3_bind_int(db_statement, field_index++, info->uid);
390 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
392 sqlite3_ret = sqlite3_step(db_statement);
394 NOTIFICATION_INFO("sqlite3_step returns[%d]", sqlite3_ret);
396 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
397 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
403 sqlite3_finalize(db_statement);
405 NOTIFICATION_INFO("foreach_package_info_callback returns[%d]", err);
409 EXPORT_API int notification_setting_refresh_setting_table(uid_t uid)
411 int err = NOTIFICATION_ERROR_NONE;
413 int sqlite3_ret = SQLITE_OK;
414 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
415 pkgmgrinfo_pkginfo_filter_h filter;
416 setting_local_info info;
418 NOTIFICATION_ERR("refresh seeting table [%d]", uid);
419 sqlite3_ret = db_util_open(DBPATH, &db, 0);
421 if (sqlite3_ret != SQLITE_OK || db == NULL) {
422 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
423 err = NOTIFICATION_ERROR_FROM_DB;
427 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
429 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
430 if (pkgmgr_ret != PMINFO_R_OK) {
431 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
432 err = NOTIFICATION_ERROR_FROM_DB;
436 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(filter, PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, NOTIFICATION_PRIVILEGE);
437 if (pkgmgr_ret != PMINFO_R_OK) {
438 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
439 err = NOTIFICATION_ERROR_FROM_DB;
445 pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, foreach_package_info_callback, &info, uid);
446 if (pkgmgr_ret != PMINFO_R_OK) {
447 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
448 err = NOTIFICATION_ERROR_FROM_DB;
452 pkgmgrinfo_pkginfo_filter_destroy(filter);
458 if (err == NOTIFICATION_ERROR_NONE)
459 sqlite3_exec(db, "END;", NULL, NULL, NULL);
461 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
463 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
464 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
467 NOTIFICATION_INFO("notification_setting_refresh_setting_table returns [%08X]", err);
473 OPERATION_TYPE_INSERT_RECORD = 0,
474 OPERATION_TYPE_DELETE_RECORD = 1,
475 } notification_setting_operation_type;
477 static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name, uid_t uid)
480 sqlite3_stmt *db_statement = NULL;
481 int sqlite3_ret = SQLITE_OK;
483 bool is_package_in_setting_table = false;
484 int err = NOTIFICATION_ERROR_NONE;
486 sqlite3_ret = db_util_open(DBPATH, &db, 0);
488 if (sqlite3_ret != SQLITE_OK || db == NULL) {
489 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
490 err = NOTIFICATION_ERROR_FROM_DB;
494 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
496 is_package_in_setting_table = _is_package_in_setting_table(db, package_name, uid);
498 switch (operation_type) {
499 case OPERATION_TYPE_INSERT_RECORD:
500 if (is_package_in_setting_table == true) {
501 NOTIFICATION_INFO("[%s] is already exist", package_name);
504 NOTIFICATION_INFO("[%s] will be inserted", package_name);
505 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
508 case OPERATION_TYPE_DELETE_RECORD:
509 if (is_package_in_setting_table == false) {
510 NOTIFICATION_INFO("[%s] is not exist", package_name);
513 NOTIFICATION_INFO("[%s] will be removed", package_name);
514 sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE uid = ? AND package_name = ? ", -1, &db_statement, NULL);
520 if (sqlite3_ret != SQLITE_OK) {
521 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
522 err = NOTIFICATION_ERROR_FROM_DB;
526 sqlite3_bind_int(db_statement, field_index++, uid);
527 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
529 sqlite3_ret = sqlite3_step(db_statement);
531 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
532 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
533 err = NOTIFICATION_ERROR_FROM_DB;
538 sqlite3_finalize(db_statement);
541 NOTIFICATION_INFO("err [%d]", err);
542 if (err == NOTIFICATION_ERROR_NONE)
543 sqlite3_exec(db, "END;", NULL, NULL, NULL);
545 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
548 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
549 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
556 bool privilege_info_cb(const char *privilege_name, void *user_data)
558 bool *found = user_data;
560 if (privilege_name && strcmp(NOTIFICATION_PRIVILEGE, privilege_name) == 0) {
568 EXPORT_API int notification_setting_insert_package_for_uid(const char *package_id, uid_t uid)
570 int err = NOTIFICATION_ERROR_NONE;
571 err = _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id, uid);
576 EXPORT_API int notification_setting_delete_package_for_uid(const char *package_id, uid_t uid)
578 return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id, uid);
581 /* system setting --------------------------------*/
583 EXPORT_API int notification_system_setting_load_system_setting_for_uid(notification_system_setting_h *system_setting, uid_t uid)
585 int ret = NOTIFICATION_ERROR_NONE;
586 if (system_setting == NULL) {
587 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
588 return NOTIFICATION_ERROR_INVALID_PARAMETER;
590 ret = notification_ipc_request_load_system_setting(system_setting, uid);
595 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
597 return notification_system_setting_load_system_setting_for_uid(system_setting, getuid());
600 EXPORT_API int notification_system_setting_update_system_setting_for_uid(notification_system_setting_h system_setting, uid_t uid)
602 int err = NOTIFICATION_ERROR_NONE;
604 if (system_setting == NULL) {
605 NOTIFICATION_ERR("Invalid parameter\n");
606 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
610 err = notification_ipc_update_system_setting(system_setting, uid);
611 if (err != NOTIFICATION_ERROR_NONE) {
612 NOTIFICATION_ERR("notification_ipc_update_system_setting returns[%d]\n", err);
620 EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting)
622 return notification_system_setting_update_system_setting_for_uid(system_setting, getuid());
625 EXPORT_API int notification_system_setting_free_system_setting(notification_system_setting_h system_setting)
627 int err = NOTIFICATION_ERROR_NONE;
629 if (system_setting == NULL) {
630 NOTIFICATION_ERR("Invalid parameter\n");
631 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
635 /* add codes to free all properties */
637 SAFE_FREE(system_setting);
644 EXPORT_API int notification_system_setting_get_do_not_disturb(notification_system_setting_h system_setting, bool *value)
646 int err = NOTIFICATION_ERROR_NONE;
648 if (system_setting == NULL || value == NULL) {
649 NOTIFICATION_ERR("Invalid parameter\n");
650 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
654 *value = system_setting->do_not_disturb;
661 EXPORT_API int notification_system_setting_set_do_not_disturb(notification_system_setting_h system_setting, bool value)
663 int err = NOTIFICATION_ERROR_NONE;
665 if (system_setting == NULL) {
666 NOTIFICATION_ERR("Invalid parameter\n");
667 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
671 system_setting->do_not_disturb = value;
678 EXPORT_API int notification_system_setting_get_visibility_class(notification_system_setting_h system_setting, int *value)
680 int err = NOTIFICATION_ERROR_NONE;
682 if (system_setting == NULL || value == NULL) {
683 NOTIFICATION_ERR("Invalid parameter\n");
684 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
688 *value = system_setting->visibility_class;
695 EXPORT_API int notification_system_setting_set_visibility_class(notification_system_setting_h system_setting, int value)
697 int err = NOTIFICATION_ERROR_NONE;
699 if (system_setting == NULL) {
700 NOTIFICATION_ERR("Invalid parameter\n");
701 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
705 system_setting->visibility_class = value;
713 EXPORT_API int notification_setting_db_update_system_setting(int do_not_disturb, int visibility_class, uid_t uid)
715 int err = NOTIFICATION_ERROR_NONE;
719 sqlite3_stmt *db_statement = NULL;
721 sqlret = db_util_open(DBPATH, &db, 0);
723 if (sqlret != SQLITE_OK || db == NULL) {
724 NOTIFICATION_ERR("db_util_open failed [%s][%d][%s]", DBPATH, sqlret, sqlite3_errmsg(db));
725 err = NOTIFICATION_ERROR_FROM_DB;
726 goto return_close_db;
729 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
731 sqlret = sqlite3_prepare_v2(db, "INSERT OR REPLACE notification_system_setting SET do_not_disturb = ?, visibility_class = ? WHERE uid = ?;", -1, &db_statement, NULL);
733 if (sqlret != SQLITE_OK) {
734 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlret, sqlite3_errmsg(db));
735 err = NOTIFICATION_ERROR_FROM_DB;
736 goto return_close_db;
739 sqlite3_bind_int(db_statement, field_index++, do_not_disturb);
740 sqlite3_bind_int(db_statement, field_index++, visibility_class);
741 sqlite3_bind_int(db_statement, field_index++, uid);
743 sqlret = sqlite3_step(db_statement);
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;
751 sqlret = sqlite3_changes(db);
754 NOTIFICATION_WARN("No changes on DB");
759 sqlite3_finalize(db_statement);
763 if (err == NOTIFICATION_ERROR_NONE)
764 sqlite3_exec(db, "END;", NULL, NULL, NULL);
766 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
768 sqlret = db_util_close(db);
771 if (sqlret != SQLITE_OK)
772 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);