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);
71 EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting)
73 return notification_setting_get_setting_by_package_name_for_uid(package_name, setting, getuid());
78 EXPORT_API int notification_setting_get_setting(notification_setting_h *setting)
81 char *package_name = NULL;
83 package_name = notification_get_pkgname_by_pid();
85 if (package_name == NULL)
86 return NOTIFICATION_ERROR_NOT_EXIST_ID;
88 ret = notification_setting_get_setting_by_package_name(package_name, setting);
96 EXPORT_API int notification_setting_get_package_name(notification_setting_h setting, char **value)
98 int err = NOTIFICATION_ERROR_NONE;
100 if (setting == NULL || value == NULL) {
101 NOTIFICATION_ERR("Invalid parameter\n");
102 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
106 if (setting->package_name == NULL) {
107 NOTIFICATION_ERR("setting->package_name is null\n");
108 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
112 *value = SAFE_STRDUP(setting->package_name);
119 EXPORT_API int notification_setting_set_package_name(notification_setting_h setting, char *value)
121 int err = NOTIFICATION_ERROR_NONE;
123 if (setting == NULL || value == NULL) {
124 NOTIFICATION_ERR("Invalid parameter\n");
125 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
129 if (setting->package_name != NULL)
130 free(setting->package_name);
132 setting->package_name = SAFE_STRDUP(value);
139 EXPORT_API int notification_setting_get_allow_to_notify(notification_setting_h setting, bool *value)
141 int err = NOTIFICATION_ERROR_NONE;
143 if (setting == NULL || value == NULL) {
144 NOTIFICATION_ERR("Invalid parameter\n");
145 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
149 *value = setting->allow_to_notify;
156 EXPORT_API int notification_setting_set_allow_to_notify(notification_setting_h setting, bool value)
158 int err = NOTIFICATION_ERROR_NONE;
160 if (setting == NULL) {
161 NOTIFICATION_ERR("Invalid parameter\n");
162 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
166 setting->allow_to_notify = value;
173 EXPORT_API int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value)
175 int err = NOTIFICATION_ERROR_NONE;
177 if (setting == NULL || value == NULL) {
178 NOTIFICATION_ERR("Invalid parameter\n");
179 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
183 *value = setting->do_not_disturb_except;
190 EXPORT_API int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value)
192 int err = NOTIFICATION_ERROR_NONE;
194 if (setting == NULL) {
195 NOTIFICATION_ERR("Invalid parameter\n");
196 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
200 setting->do_not_disturb_except = value;
207 EXPORT_API int notification_setting_get_visibility_class(notification_setting_h setting, int *value)
209 int err = NOTIFICATION_ERROR_NONE;
211 if (setting == NULL || value == NULL) {
212 NOTIFICATION_ERR("Invalid parameter\n");
213 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
217 *value = setting->visibility_class;
224 EXPORT_API int notification_setting_set_visibility_class(notification_setting_h setting, int value)
226 int err = NOTIFICATION_ERROR_NONE;
228 if (setting == NULL) {
229 NOTIFICATION_ERR("Invalid parameter\n");
230 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
234 setting->visibility_class = value;
241 EXPORT_API int notification_setting_update_setting_for_uid(notification_setting_h setting, uid_t uid)
243 int err = NOTIFICATION_ERROR_NONE;
245 if (setting == NULL) {
246 NOTIFICATION_ERR("Invalid parameter\n");
247 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
251 err = notification_ipc_update_setting(setting, uid);
252 if (err != NOTIFICATION_ERROR_NONE) {
253 NOTIFICATION_ERR("notification_setting_update_setting returns[%d]\n", err);
261 EXPORT_API int notification_setting_update_setting(notification_setting_h setting)
263 return notification_setting_update_setting_for_uid(setting, getuid());
266 EXPORT_API int notification_setting_free_notification(notification_setting_h setting)
268 int err = NOTIFICATION_ERROR_NONE;
270 if (setting == NULL) {
271 NOTIFICATION_ERR("Invalid parameter\n");
272 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
276 SAFE_FREE(setting->package_name);
278 /* add codes to free all properties */
286 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)
288 int err = NOTIFICATION_ERROR_NONE;
293 if (package_name == NULL || strlen(package_name) == 0)
294 return NOTIFICATION_ERROR_INVALID_PARAMETER;
296 sqlret = db_util_open(DBPATH, &db, 0);
297 if (sqlret != SQLITE_OK || db == NULL) {
298 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret);
299 return NOTIFICATION_ERROR_FROM_DB;
302 sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_notify = %d, do_not_disturb_except = %d, visibility_class = %d " \
303 "WHERE package_name = %Q AND uid = %d",
304 NOTIFICATION_SETTING_DB_TABLE, allow_to_notify, do_not_disturb_except, visibility_class, package_name, uid);
306 NOTIFICATION_ERR("fail to alloc query");
307 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
308 goto return_close_db;
311 err = notification_db_exec(db, sqlbuf, NULL);
315 sqlite3_free(sqlbuf);
317 sqlret = db_util_close(db);
318 if (sqlret != SQLITE_OK)
319 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
324 static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name, uid_t uid)
326 sqlite3_stmt *db_statement = NULL;
327 int sqlite3_ret = SQLITE_OK;
331 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT package_name FROM notification_setting WHERE uid = ? AND package_name = ?", -1, &db_statement, NULL);
333 if (sqlite3_ret != SQLITE_OK) {
334 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
339 sqlite3_bind_int(db_statement, field_index++, uid);
340 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
342 sqlite3_ret = sqlite3_step(db_statement);
344 if (sqlite3_ret == SQLITE_DONE) {
345 NOTIFICATION_INFO("no matched package_name found[%s][%d]", package_name, sqlite3_ret);
350 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
351 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
357 sqlite3_finalize(db_statement);
362 static int foreach_package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
364 setting_local_info *info = (setting_local_info *)user_data;
365 sqlite3 *db = info->db;
366 sqlite3_stmt *db_statement = NULL;
367 char *package_name = NULL;
368 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
369 int sqlite3_ret = SQLITE_OK;
373 if ((pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &package_name)) != PACKAGE_MANAGER_ERROR_NONE) {
374 NOTIFICATION_ERR("package_info_get_package failed [%d]", pkgmgr_ret);
379 if (_is_package_in_setting_table(db, package_name, info->uid) == true) {
380 NOTIFICATION_INFO("uid %d [%s] is exist", info->uid, package_name);
384 NOTIFICATION_INFO("uid %d [%s] will be inserted", info->uid, package_name);
385 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
387 if (sqlite3_ret != SQLITE_OK) {
388 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
393 sqlite3_bind_int(db_statement, field_index++, info->uid);
394 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
396 sqlite3_ret = sqlite3_step(db_statement);
398 NOTIFICATION_INFO("sqlite3_step returns[%d]", sqlite3_ret);
400 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
401 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
407 sqlite3_finalize(db_statement);
409 NOTIFICATION_INFO("foreach_package_info_callback returns[%d]", err);
413 EXPORT_API int notification_setting_refresh_setting_table(uid_t uid)
415 int err = NOTIFICATION_ERROR_NONE;
417 int sqlite3_ret = SQLITE_OK;
418 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
419 pkgmgrinfo_pkginfo_filter_h filter;
420 setting_local_info info;
422 NOTIFICATION_ERR("refresh seeting table [%d]", uid);
423 sqlite3_ret = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);
424 if (sqlite3_ret != SQLITE_OK || db == NULL) {
425 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
426 err = NOTIFICATION_ERROR_FROM_DB;
430 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
432 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
433 if (pkgmgr_ret != PMINFO_R_OK) {
434 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
435 err = NOTIFICATION_ERROR_FROM_DB;
439 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(filter, PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, NOTIFICATION_PRIVILEGE);
440 if (pkgmgr_ret != PMINFO_R_OK) {
441 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
442 err = NOTIFICATION_ERROR_FROM_DB;
448 pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, foreach_package_info_callback, &info, uid);
449 if (pkgmgr_ret != PMINFO_R_OK) {
450 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
451 err = NOTIFICATION_ERROR_FROM_DB;
455 pkgmgrinfo_pkginfo_filter_destroy(filter);
461 if (err == NOTIFICATION_ERROR_NONE)
462 sqlite3_exec(db, "END;", NULL, NULL, NULL);
464 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
466 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
467 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
470 NOTIFICATION_INFO("notification_setting_refresh_setting_table returns [%08X]", err);
476 OPERATION_TYPE_INSERT_RECORD = 0,
477 OPERATION_TYPE_DELETE_RECORD = 1,
478 } notification_setting_operation_type;
480 static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name, uid_t uid)
483 sqlite3_stmt *db_statement = NULL;
484 int sqlite3_ret = SQLITE_OK;
486 bool is_package_in_setting_table = false;
487 int err = NOTIFICATION_ERROR_NONE;
489 sqlite3_ret = db_util_open(DBPATH, &db, 0);
491 if (sqlite3_ret != SQLITE_OK || db == NULL) {
492 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
493 err = NOTIFICATION_ERROR_FROM_DB;
497 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
499 is_package_in_setting_table = _is_package_in_setting_table(db, package_name, uid);
501 switch (operation_type) {
502 case OPERATION_TYPE_INSERT_RECORD:
503 if (is_package_in_setting_table == true) {
504 NOTIFICATION_INFO("[%s] is already exist", package_name);
507 NOTIFICATION_INFO("[%s] will be inserted", package_name);
508 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (uid, package_name) VALUES (?, ?) ", -1, &db_statement, NULL);
511 case OPERATION_TYPE_DELETE_RECORD:
512 if (is_package_in_setting_table == false) {
513 NOTIFICATION_INFO("[%s] is not exist", package_name);
516 NOTIFICATION_INFO("[%s] will be removed", package_name);
517 sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE uid = ? AND package_name = ? ", -1, &db_statement, NULL);
523 if (sqlite3_ret != SQLITE_OK) {
524 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
525 err = NOTIFICATION_ERROR_FROM_DB;
529 sqlite3_bind_int(db_statement, field_index++, uid);
530 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
532 sqlite3_ret = sqlite3_step(db_statement);
534 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
535 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
536 err = NOTIFICATION_ERROR_FROM_DB;
541 sqlite3_finalize(db_statement);
544 NOTIFICATION_INFO("err [%d]", err);
545 if (err == NOTIFICATION_ERROR_NONE)
546 sqlite3_exec(db, "END;", NULL, NULL, NULL);
548 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
551 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
552 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
559 /* LCOV_EXCL_START */
560 bool privilege_info_cb(const char *privilege_name, void *user_data)
562 bool *found = user_data;
564 if (privilege_name && strcmp(NOTIFICATION_PRIVILEGE, privilege_name) == 0) {
573 EXPORT_API int notification_setting_insert_package_for_uid(const char *package_id, uid_t uid)
575 int err = NOTIFICATION_ERROR_NONE;
576 err = _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id, uid);
581 EXPORT_API int notification_setting_delete_package_for_uid(const char *package_id, uid_t uid)
583 return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id, uid);
586 /* system setting --------------------------------*/
588 EXPORT_API int notification_system_setting_load_system_setting_for_uid(notification_system_setting_h *system_setting, uid_t uid)
590 int ret = NOTIFICATION_ERROR_NONE;
591 if (system_setting == NULL) {
592 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
593 return NOTIFICATION_ERROR_INVALID_PARAMETER;
595 ret = notification_ipc_request_load_system_setting(system_setting, uid);
600 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
602 return notification_system_setting_load_system_setting_for_uid(system_setting, getuid());
605 EXPORT_API int notification_system_setting_update_system_setting_for_uid(notification_system_setting_h system_setting, uid_t uid)
607 int err = NOTIFICATION_ERROR_NONE;
609 if (system_setting == NULL) {
610 NOTIFICATION_ERR("Invalid parameter\n");
611 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
615 err = notification_ipc_update_system_setting(system_setting, uid);
616 if (err != NOTIFICATION_ERROR_NONE) {
617 NOTIFICATION_ERR("notification_ipc_update_system_setting returns[%d]\n", err);
625 EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting)
627 return notification_system_setting_update_system_setting_for_uid(system_setting, getuid());
630 EXPORT_API int notification_system_setting_free_system_setting(notification_system_setting_h system_setting)
632 int err = NOTIFICATION_ERROR_NONE;
634 if (system_setting == NULL) {
635 NOTIFICATION_ERR("Invalid parameter\n");
636 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
640 /* add codes to free all properties */
642 SAFE_FREE(system_setting);
649 EXPORT_API int notification_system_setting_get_do_not_disturb(notification_system_setting_h system_setting, bool *value)
651 int err = NOTIFICATION_ERROR_NONE;
653 if (system_setting == NULL || value == NULL) {
654 NOTIFICATION_ERR("Invalid parameter\n");
655 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
659 *value = system_setting->do_not_disturb;
666 EXPORT_API int notification_system_setting_set_do_not_disturb(notification_system_setting_h system_setting, bool value)
668 int err = NOTIFICATION_ERROR_NONE;
670 if (system_setting == NULL) {
671 NOTIFICATION_ERR("Invalid parameter\n");
672 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
676 system_setting->do_not_disturb = value;
683 EXPORT_API int notification_system_setting_get_visibility_class(notification_system_setting_h system_setting, int *value)
685 int err = NOTIFICATION_ERROR_NONE;
687 if (system_setting == NULL || value == NULL) {
688 NOTIFICATION_ERR("Invalid parameter\n");
689 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
693 *value = system_setting->visibility_class;
700 EXPORT_API int notification_system_setting_set_visibility_class(notification_system_setting_h system_setting, int value)
702 int err = NOTIFICATION_ERROR_NONE;
704 if (system_setting == NULL) {
705 NOTIFICATION_ERR("Invalid parameter\n");
706 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
710 system_setting->visibility_class = value;
718 EXPORT_API int notification_setting_db_update_system_setting(int do_not_disturb, int visibility_class, uid_t uid)
720 int err = NOTIFICATION_ERROR_NONE;
724 sqlite3_stmt *db_statement = NULL;
726 sqlret = db_util_open(DBPATH, &db, 0);
728 if (sqlret != SQLITE_OK || db == NULL) {
729 NOTIFICATION_ERR("db_util_open failed [%s][%d][%s]", DBPATH, sqlret, sqlite3_errmsg(db));
730 err = NOTIFICATION_ERROR_FROM_DB;
731 goto return_close_db;
734 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
735 sqlret = sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO notification_system_setting (uid, do_not_disturb, visibility_class) values(?, ?, ?);", -1, &db_statement, NULL);
737 if (sqlret != SQLITE_OK) {
738 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlret, sqlite3_errmsg(db));
739 err = NOTIFICATION_ERROR_FROM_DB;
740 goto return_close_db;
743 sqlite3_bind_int(db_statement, field_index++, uid);
744 sqlite3_bind_int(db_statement, field_index++, do_not_disturb);
745 sqlite3_bind_int(db_statement, field_index++, visibility_class);
747 sqlret = sqlite3_step(db_statement);
748 if (sqlret != SQLITE_OK && sqlret != SQLITE_DONE) {
749 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlret, sqlite3_errmsg(db));
750 err = NOTIFICATION_ERROR_FROM_DB;
751 goto return_close_db;
754 sqlret = sqlite3_changes(db);
757 NOTIFICATION_WARN("No changes on DB");
762 sqlite3_finalize(db_statement);
766 if (err == NOTIFICATION_ERROR_NONE)
767 sqlite3_exec(db, "END;", NULL, NULL, NULL);
769 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
771 sqlret = db_util_close(db);
774 if (sqlret != SQLITE_OK)
775 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);