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"
38 EXPORT_API int notification_setting_get_setting_array(notification_setting_h *setting_array, int *count)
40 int ret = NOTIFICATION_ERROR_NONE;
41 if (setting_array == NULL || count == NULL) {
42 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
43 return NOTIFICATION_ERROR_INVALID_PARAMETER;
45 ret = notification_ipc_request_get_setting_array(setting_array, count);
49 EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting)
51 int ret = NOTIFICATION_ERROR_NONE;
52 if (package_name == NULL || setting == NULL) {
53 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
54 return NOTIFICATION_ERROR_INVALID_PARAMETER;
56 ret = notification_ipc_request_get_setting_by_package_name(package_name, setting);
60 EXPORT_API int notification_setting_get_setting(notification_setting_h *setting)
63 char *package_name = NULL;
65 package_name = notification_get_pkgname_by_pid();
67 if (package_name == NULL)
68 return NOTIFICATION_ERROR_NOT_EXIST_ID;
70 ret = notification_setting_get_setting_by_package_name(package_name, setting);
77 EXPORT_API int notification_setting_get_package_name(notification_setting_h setting, char **value)
79 int err = NOTIFICATION_ERROR_NONE;
81 if (setting == NULL || value == NULL) {
82 NOTIFICATION_ERR("Invalid parameter\n");
83 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
87 if (setting->package_name == NULL) {
88 NOTIFICATION_ERR("setting->package_name is null\n");
89 err = NOTIFICATION_ERROR_NOT_EXIST_ID;
93 *value = SAFE_STRDUP(setting->package_name);
100 EXPORT_API int notification_setting_set_package_name(notification_setting_h setting, char *value)
102 int err = NOTIFICATION_ERROR_NONE;
104 if (setting == NULL || value == NULL) {
105 NOTIFICATION_ERR("Invalid parameter\n");
106 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
110 if (setting->package_name != NULL)
111 free(setting->package_name);
113 setting->package_name = SAFE_STRDUP(value);
120 EXPORT_API int notification_setting_get_allow_to_notify(notification_setting_h setting, bool *value)
122 int err = NOTIFICATION_ERROR_NONE;
124 if (setting == NULL || value == NULL) {
125 NOTIFICATION_ERR("Invalid parameter\n");
126 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
130 *value = setting->allow_to_notify;
137 EXPORT_API int notification_setting_set_allow_to_notify(notification_setting_h setting, bool value)
139 int err = NOTIFICATION_ERROR_NONE;
141 if (setting == NULL) {
142 NOTIFICATION_ERR("Invalid parameter\n");
143 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
147 setting->allow_to_notify = value;
154 EXPORT_API int notification_setting_get_do_not_disturb_except(notification_setting_h setting, bool *value)
156 int err = NOTIFICATION_ERROR_NONE;
158 if (setting == NULL || value == NULL) {
159 NOTIFICATION_ERR("Invalid parameter\n");
160 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
164 *value = setting->do_not_disturb_except;
171 EXPORT_API int notification_setting_set_do_not_disturb_except(notification_setting_h setting, bool value)
173 int err = NOTIFICATION_ERROR_NONE;
175 if (setting == NULL) {
176 NOTIFICATION_ERR("Invalid parameter\n");
177 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
181 setting->do_not_disturb_except = value;
188 EXPORT_API int notification_setting_get_visibility_class(notification_setting_h setting, int *value)
190 int err = NOTIFICATION_ERROR_NONE;
192 if (setting == NULL || value == NULL) {
193 NOTIFICATION_ERR("Invalid parameter\n");
194 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
198 *value = setting->visibility_class;
205 EXPORT_API int notification_setting_set_visibility_class(notification_setting_h setting, int value)
207 int err = NOTIFICATION_ERROR_NONE;
209 if (setting == NULL) {
210 NOTIFICATION_ERR("Invalid parameter\n");
211 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
215 setting->visibility_class = value;
222 EXPORT_API int notification_setting_update_setting(notification_setting_h setting)
224 int err = NOTIFICATION_ERROR_NONE;
226 if (setting == NULL) {
227 NOTIFICATION_ERR("Invalid parameter\n");
228 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
232 err = notification_ipc_update_setting(setting);
233 if (err != NOTIFICATION_ERROR_NONE) {
234 NOTIFICATION_ERR("notification_setting_update_setting returns[%d]\n", err);
242 EXPORT_API int notification_setting_free_notification(notification_setting_h setting)
244 int err = NOTIFICATION_ERROR_NONE;
246 if (setting == NULL) {
247 NOTIFICATION_ERR("Invalid parameter\n");
248 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
252 SAFE_FREE(setting->package_name);
254 /* add codes to free all properties */
262 EXPORT_API int notification_setting_db_update(const char *package_name, int allow_to_notify, int do_not_disturb_except, int visibility_class)
264 int err = NOTIFICATION_ERROR_NONE;
269 if (package_name == NULL || strlen(package_name) == 0)
270 return NOTIFICATION_ERROR_INVALID_PARAMETER;
272 sqlret = db_util_open(DBPATH, &db, 0);
273 if (sqlret != SQLITE_OK || db == NULL) {
274 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret);
275 return NOTIFICATION_ERROR_FROM_DB;
278 sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_notify = %d, do_not_disturb_except = %d, visibility_class = %d " \
279 "WHERE package_name = %Q",
280 NOTIFICATION_SETTING_DB_TABLE, allow_to_notify, do_not_disturb_except, visibility_class, package_name);
282 NOTIFICATION_ERR("fail to alloc query");
283 err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
284 goto return_close_db;
287 err = notification_db_exec(db, sqlbuf, NULL);
291 sqlite3_free(sqlbuf);
293 sqlret = db_util_close(db);
294 if (sqlret != SQLITE_OK)
295 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);
300 static bool _is_package_in_setting_table(sqlite3 *db, const char *package_name)
302 sqlite3_stmt *db_statement = NULL;
303 int sqlite3_ret = SQLITE_OK;
307 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT package_name FROM notification_setting WHERE package_name = ?", -1, &db_statement, NULL);
309 if (sqlite3_ret != SQLITE_OK) {
310 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
315 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
317 sqlite3_ret = sqlite3_step(db_statement);
319 if (sqlite3_ret == SQLITE_DONE) {
320 NOTIFICATION_INFO("no matched package_name found[%s][%d]", package_name, sqlite3_ret);
325 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
326 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
332 sqlite3_finalize(db_statement);
337 static int foreach_package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
339 sqlite3 *db = user_data;
340 sqlite3_stmt *db_statement = NULL;
341 char *package_name = NULL;
342 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
343 int sqlite3_ret = SQLITE_OK;
347 if ((pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &package_name)) != PACKAGE_MANAGER_ERROR_NONE) {
348 NOTIFICATION_ERR("package_info_get_package failed [%d]", pkgmgr_ret);
353 if (_is_package_in_setting_table(db, package_name) == true) {
354 NOTIFICATION_INFO("[%s] is exist", package_name);
358 NOTIFICATION_INFO("[%s] will be inserted", package_name);
360 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (package_name) VALUES (?) ", -1, &db_statement, NULL);
362 if (sqlite3_ret != SQLITE_OK) {
363 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
368 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
370 sqlite3_ret = sqlite3_step(db_statement);
372 NOTIFICATION_INFO("sqlite3_step returns[%d]", sqlite3_ret);
374 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
375 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
381 sqlite3_finalize(db_statement);
383 NOTIFICATION_INFO("foreach_package_info_callback returns[%d]", err);
387 EXPORT_API int notification_setting_refresh_setting_table()
389 int err = NOTIFICATION_ERROR_NONE;
391 int sqlite3_ret = SQLITE_OK;
392 int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
393 pkgmgrinfo_pkginfo_filter_h filter;
395 sqlite3_ret = db_util_open(DBPATH, &db, 0);
397 if (sqlite3_ret != SQLITE_OK || db == NULL) {
398 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
399 err = NOTIFICATION_ERROR_FROM_DB;
403 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
405 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
406 if (pkgmgr_ret != PMINFO_R_OK) {
407 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
408 err = NOTIFICATION_ERROR_FROM_DB;
412 pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(filter, PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, NOTIFICATION_PRIVILEGE);
413 if (pkgmgr_ret != PMINFO_R_OK) {
414 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
415 err = NOTIFICATION_ERROR_FROM_DB;
420 * DEFAULT_UID is owner's uid(5001)
421 * currently this api do not support multi-user.
423 pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, foreach_package_info_callback, db, tzplatform_getuid(TZ_SYS_DEFAULT_USER));
424 if (pkgmgr_ret != PMINFO_R_OK) {
425 NOTIFICATION_ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
426 err = NOTIFICATION_ERROR_FROM_DB;
430 pkgmgrinfo_pkginfo_filter_destroy(filter);
436 if (err == NOTIFICATION_ERROR_NONE)
437 sqlite3_exec(db, "END;", NULL, NULL, NULL);
439 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
441 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
442 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
445 NOTIFICATION_INFO("notification_setting_refresh_setting_table returns [%08X]", err);
451 OPERATION_TYPE_INSERT_RECORD = 0,
452 OPERATION_TYPE_DELETE_RECORD = 1,
453 } notification_setting_operation_type;
455 static int _notification_setting_alter_package_list(notification_setting_operation_type operation_type, const char *package_name)
458 sqlite3_stmt *db_statement = NULL;
459 int sqlite3_ret = SQLITE_OK;
461 bool is_package_in_setting_table = false;
462 int err = NOTIFICATION_ERROR_NONE;
464 sqlite3_ret = db_util_open(DBPATH, &db, 0);
466 if (sqlite3_ret != SQLITE_OK || db == NULL) {
467 NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlite3_ret);
468 err = NOTIFICATION_ERROR_FROM_DB;
472 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
474 is_package_in_setting_table = _is_package_in_setting_table(db, package_name);
476 switch (operation_type) {
477 case OPERATION_TYPE_INSERT_RECORD:
478 if (is_package_in_setting_table == true) {
479 NOTIFICATION_INFO("[%s] is already exist", package_name);
482 NOTIFICATION_INFO("[%s] will be inserted", package_name);
483 sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO notification_setting (package_name) VALUES (?) ", -1, &db_statement, NULL);
486 case OPERATION_TYPE_DELETE_RECORD:
487 if (is_package_in_setting_table == false) {
488 NOTIFICATION_INFO("[%s] is not exist", package_name);
491 NOTIFICATION_INFO("[%s] will be removed", package_name);
492 sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM notification_setting WHERE package_name = ? ", -1, &db_statement, NULL);
498 if (sqlite3_ret != SQLITE_OK) {
499 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
500 err = NOTIFICATION_ERROR_FROM_DB;
504 sqlite3_bind_text(db_statement, field_index++, package_name, -1, SQLITE_TRANSIENT);
506 sqlite3_ret = sqlite3_step(db_statement);
508 if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
509 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
510 err = NOTIFICATION_ERROR_FROM_DB;
515 sqlite3_finalize(db_statement);
518 NOTIFICATION_INFO("err [%d]", err);
519 if (err == NOTIFICATION_ERROR_NONE)
520 sqlite3_exec(db, "END;", NULL, NULL, NULL);
522 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
525 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
526 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlite3_ret);
533 bool privilege_info_cb(const char *privilege_name, void *user_data)
535 bool *found = user_data;
537 if (privilege_name && strcmp(NOTIFICATION_PRIVILEGE, privilege_name) == 0) {
545 static bool _has_privilege(const char *package_id)
548 int error_from_package_info = PACKAGE_MANAGER_ERROR_NONE;
549 package_info_h package_info = NULL;
551 error_from_package_info = package_info_create(package_id, &package_info);
552 if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
553 NOTIFICATION_ERR("package_info_create failed [%d]", error_from_package_info);
557 error_from_package_info = package_info_foreach_privilege_info(package_info, privilege_info_cb, &found);
559 if (error_from_package_info != PACKAGE_MANAGER_ERROR_NONE) {
560 NOTIFICATION_ERR("package_info_foreach_privilege_info failed [%d]", error_from_package_info);
567 package_info_destroy(package_info);
572 EXPORT_API int notification_setting_insert_package(const char *package_id)
574 int err = NOTIFICATION_ERROR_NONE;
576 if (_has_privilege(package_id) == true)
577 err = _notification_setting_alter_package_list(OPERATION_TYPE_INSERT_RECORD, package_id);
582 EXPORT_API int notification_setting_delete_package(const char *package_id)
584 return _notification_setting_alter_package_list(OPERATION_TYPE_DELETE_RECORD, package_id);
587 /* system setting --------------------------------*/
589 EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting)
591 int ret = NOTIFICATION_ERROR_NONE;
592 if (system_setting == NULL) {
593 NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
594 return NOTIFICATION_ERROR_INVALID_PARAMETER;
596 ret = notification_ipc_request_load_system_setting(system_setting);
601 EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting)
603 int err = NOTIFICATION_ERROR_NONE;
605 if (system_setting == NULL) {
606 NOTIFICATION_ERR("Invalid parameter\n");
607 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
611 err = notification_ipc_update_system_setting(system_setting);
612 if (err != NOTIFICATION_ERROR_NONE) {
613 NOTIFICATION_ERR("notification_ipc_update_system_setting returns[%d]\n", err);
621 EXPORT_API int notification_system_setting_free_system_setting(notification_system_setting_h system_setting)
623 int err = NOTIFICATION_ERROR_NONE;
625 if (system_setting == NULL) {
626 NOTIFICATION_ERR("Invalid parameter\n");
627 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
631 /* add codes to free all properties */
633 SAFE_FREE(system_setting);
640 EXPORT_API int notification_system_setting_get_do_not_disturb(notification_system_setting_h system_setting, bool *value)
642 int err = NOTIFICATION_ERROR_NONE;
644 if (system_setting == NULL || value == NULL) {
645 NOTIFICATION_ERR("Invalid parameter\n");
646 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
650 *value = system_setting->do_not_disturb;
657 EXPORT_API int notification_system_setting_set_do_not_disturb(notification_system_setting_h system_setting, bool value)
659 int err = NOTIFICATION_ERROR_NONE;
661 if (system_setting == NULL) {
662 NOTIFICATION_ERR("Invalid parameter\n");
663 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
667 system_setting->do_not_disturb = value;
674 EXPORT_API int notification_system_setting_get_visibility_class(notification_system_setting_h system_setting, int *value)
676 int err = NOTIFICATION_ERROR_NONE;
678 if (system_setting == NULL || value == NULL) {
679 NOTIFICATION_ERR("Invalid parameter\n");
680 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
684 *value = system_setting->visibility_class;
691 EXPORT_API int notification_system_setting_set_visibility_class(notification_system_setting_h system_setting, int value)
693 int err = NOTIFICATION_ERROR_NONE;
695 if (system_setting == NULL) {
696 NOTIFICATION_ERR("Invalid parameter\n");
697 err = NOTIFICATION_ERROR_INVALID_PARAMETER;
701 system_setting->visibility_class = value;
709 EXPORT_API int notification_setting_db_update_system_setting(int do_not_disturb, int visibility_class)
711 int err = NOTIFICATION_ERROR_NONE;
715 sqlite3_stmt *db_statement = NULL;
717 sqlret = db_util_open(DBPATH, &db, 0);
719 if (sqlret != SQLITE_OK || db == NULL) {
720 NOTIFICATION_ERR("db_util_open failed [%s][%d][%s]", DBPATH, sqlret, sqlite3_errmsg(db));
721 err = NOTIFICATION_ERROR_FROM_DB;
722 goto return_close_db;
725 sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
727 sqlret = sqlite3_prepare_v2(db, "UPDATE notification_system_setting SET do_not_disturb = ?, visibility_class = ?;", -1, &db_statement, NULL);
729 if (sqlret != SQLITE_OK) {
730 NOTIFICATION_ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlret, sqlite3_errmsg(db));
731 err = NOTIFICATION_ERROR_FROM_DB;
732 goto return_close_db;
735 sqlite3_bind_int(db_statement, field_index++, do_not_disturb);
736 sqlite3_bind_int(db_statement, field_index++, visibility_class);
738 sqlret = sqlite3_step(db_statement);
740 if (sqlret != SQLITE_OK && sqlret != SQLITE_DONE) {
741 NOTIFICATION_ERR("sqlite3_step failed [%d][%s]", sqlret, sqlite3_errmsg(db));
742 err = NOTIFICATION_ERROR_FROM_DB;
743 goto return_close_db;
746 sqlret = sqlite3_changes(db);
749 NOTIFICATION_WARN("No changes on DB");
754 sqlite3_finalize(db_statement);
758 if (err == NOTIFICATION_ERROR_NONE)
759 sqlite3_exec(db, "END;", NULL, NULL, NULL);
761 sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
763 sqlret = db_util_close(db);
766 if (sqlret != SQLITE_OK)
767 NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret);