From 1a3acd7e3f047f73df92142433a35e53dc5e8ab7 Mon Sep 17 00:00:00 2001 From: Myungki Lee Date: Mon, 19 Sep 2016 19:10:19 +0900 Subject: [PATCH] Add apis for dnd_allow_exception - notification_system_setting_set_dnd_allow_exceptions() notification_system_setting_get_dnd_allow_exceptions() Change-Id: I9e2fda4ca1b705383a7d74dea5198eef99c19063 Signed-off-by: Myungki Lee --- include/notification_ipc.h | 5 ++ include/notification_private.h | 1 + include/notification_setting_internal.h | 112 +++++++++++++++++++++++++++++++ include/notification_setting_service.h | 2 + src/notification_db.c | 8 ++- src/notification_ipc.c | 75 ++++++++++++++++++++- src/notification_setting.c | 72 ++++++++++++++++++++ src/notification_setting_service.c | 113 ++++++++++++++++++++++++++++++++ test-app/main.c | 9 ++- 9 files changed, 394 insertions(+), 3 deletions(-) diff --git a/include/notification_ipc.h b/include/notification_ipc.h index db14a28..dcde048 100755 --- a/include/notification_ipc.h +++ b/include/notification_ipc.h @@ -89,6 +89,11 @@ int notification_ipc_request_create_from_package_template(notification_h noti, const char *pkgname, const char *template_name); int notification_ipc_get_noti_block_state(const char *pkgname, int *do_not_disturb, int *do_not_disturb_except, int *allow_to_notify, uid_t uid); +GVariant * notification_ipc_make_gvariant_from_dnd_allow_exception( + struct notification_system_setting_dnd_allow_exception *dnd_allow_exception); +int notification_ipc_make_dnd_allow_exception_from_gvariant( + struct notification_system_setting_dnd_allow_exception *dnd_allow_exception, + GVariant *variant); #ifdef __cplusplus } diff --git a/include/notification_private.h b/include/notification_private.h index f895b9b..167b1c5 100644 --- a/include/notification_private.h +++ b/include/notification_private.h @@ -33,6 +33,7 @@ #define NOTIFICATION_SETTING_DB_TABLE "notification_setting" #define NOTIFICATION_SYSTEM_SETTING_DB_TABLE "notification_system_setting" +#define NOTIFICATION_DND_ALLOW_EXCEPTION "dnd_allow_exception" struct _notification { notification_type_e type; diff --git a/include/notification_setting_internal.h b/include/notification_setting_internal.h index 3011cae..cbe0cae 100644 --- a/include/notification_setting_internal.h +++ b/include/notification_setting_internal.h @@ -19,6 +19,7 @@ #include #include +#include #include "notification.h" #include "notification_setting.h" @@ -27,6 +28,7 @@ extern "C" { #endif typedef struct notification_system_setting *notification_system_setting_h; +typedef struct notification_system_setting_dnd_allow_exception *dnd_allow_exception_h; /* * The prototype of handler that 'Do not disturb' mode set schdule changed alarm. @@ -57,6 +59,26 @@ typedef enum lock_screen_content_level { DO_NOT_SHOW_NOTIFICATIONS, } lock_screen_content_level_e; +/** + * @brief Enumeration for do_not_disturb allow exception type. + * @since_tizen 3.0 + */ +typedef enum dnd_allow_exception_type { + NOTIFICATION_DND_ALLOWED_CALLS = 0, + /* possible to add */ +} dnd_allow_exception_type_e; + +/** + * @brief Enumeration for allowed_calls. + * @since_tizen 3.0 + */ +typedef enum notification_dnd_allowed_calls { + NOTIFICATION_DND_ALLOWED_CALLS_EVERYONE = 0, + NOTIFICATION_DND_ALLOWED_CALLS_CONTACT, + NOTIFICATION_DND_ALLOWED_CALLS_FAVORITE, + NOTIFICATION_DND_ALLOWED_CALLS_NOBODY, +} notification_dnd_allowed_calls_e; + /* Application setting */ struct notification_setting { char *package_name; @@ -78,6 +100,13 @@ struct notification_system_setting { int dnd_end_hour; int dnd_end_min; lock_screen_content_level_e lock_screen_content_level; + GList *dnd_allow_exceptions; +}; + +/* dnd_allow_exception */ +struct notification_system_setting_dnd_allow_exception { + int type; + int value; }; /** @@ -1156,6 +1185,89 @@ int notification_system_setting_set_lock_screen_content(notification_system_sett /* * @internal + * @brief Gets a value of the do_not_disturb allow exceptions. + * @since_tizen 3.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/notification + * @param[in] setting The notification system setting handle + * @param[in] dnd_allow_exception_type_e The exceptional item of do_not_distrub + * @param[out] value The value of the exceptional item + * @return #NOTIFICATION_ERROR_NONE on success, + * otherwise any other value on failure + * @retval #NOTIFICATION_ERROR_NONE Success + * @retval #NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter + * @par sample code: + * @code +#include +... +{ + int noti_err = 0; + int value; + notification_system_setting_h setting = NULL; + ... + noti_err = notifiacation_system_setting_load_system_setting(&setting); + if (noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + + noti_err = notification_system_setting_get_dnd_allow_exceptions(setting, ALLOWED_CALLS, &value); + if (noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + ... + notification_system_setting_free_system_setting(setting); + + return 0; + +} + * @endcode + */ +int notification_system_setting_get_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int *value); + +/* + * @internal + * @brief Sets a value of the do_not_disturb allow exceptions. + * @since_tizen 3.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/notification + * @param[in] setting The notification system setting handle + * @param[in] dnd_allow_exception_type_e The exceptional item of do_not_distrub + * @param[in] value The value of the exceptional item + * @return #NOTIFICATION_ERROR_NONE on success, + * otherwise any other value on failure + * @retval #NOTIFICATION_ERROR_NONE Success + * @retval #NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #NOTIFICATION_ERROR_OUT_OF_MEMORY out of memory + * @par sample code: + * @code +#include +... +{ + int noti_err = 0; + int value = 0; + notification_system_setting_h setting = NULL; + ... + noti_err = notifiacation_system_setting_load_system_setting(&setting); + if (noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + + noti_err = notification_system_setting_set_dnd_allow_exceptions(setting, ALLOWED_CALLS, value); + if (noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + ... + notification_system_setting_free_system_setting(setting); + + return 0; + +} + * @endcode + */ +int notification_system_setting_set_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int value); + +/* + * @internal * @brief Registers a callback for 'Do not disturb' mode setting schedule is start or end. * @since_tizen 3.0 * @privlevel public diff --git a/include/notification_setting_service.h b/include/notification_setting_service.h index 2ec8f45..592cff0 100644 --- a/include/notification_setting_service.h +++ b/include/notification_setting_service.h @@ -41,6 +41,8 @@ int noti_setting_get_setting_array(notification_setting_h *setting_array, int *c int noti_system_setting_load_system_setting(notification_system_setting_h *system_setting, uid_t uid); int notification_system_setting_get_dnd_schedule_enabled_uid(uid_t **uids, int *count); int notification_get_dnd_and_allow_to_notify(const char *pkgname, int *do_not_disturb, int *do_not_disturb_except, int *allow_to_notify, uid_t uid); +int notification_system_setting_load_dnd_allow_exception(dnd_allow_exception_h *dnd_allow_exception, int *count, uid_t uid); +int notification_system_setting_update_dnd_allow_exception(int type, int value, uid_t uid); #ifdef __cplusplus } #endif diff --git a/src/notification_db.c b/src/notification_db.c index 58b5151..5c9c414 100755 --- a/src/notification_db.c +++ b/src/notification_db.c @@ -145,7 +145,13 @@ create table if not exists noti_list ( \ dnd_end_min INTEGER DEFAULT 0, \ lock_screen_content_level INTEGER DEFAULT 0, \ UNIQUE (uid) \ - );\ + ); \ + CREATE TABLE IF NOT EXISTS dnd_allow_exception ( \ + uid INTEGER, \ + type INTEGER DEFAULT 0, \ + value INTEGER DEFAULT 0, \ + UNIQUE (uid, type) \ + ); \ CREATE TABLE IF NOT EXISTS noti_template ( \ type INTEGER NOT NULL, \ layout INTEGER NOT NULL default 0, \ diff --git a/src/notification_ipc.c b/src/notification_ipc.c index 546f9a1..1f8d9ed 100755 --- a/src/notification_ipc.c +++ b/src/notification_ipc.c @@ -1227,10 +1227,16 @@ int notification_ipc_request_get_setting_by_package_name( int notification_ipc_request_load_system_setting(notification_system_setting_h *setting, uid_t uid) { int result; + int count; + int index = 0; GDBusMessage *reply = NULL; GVariant *setting_body; GVariant *reply_body; + GVariant *iter_body; + GVariantIter *iter; notification_system_setting_h result_setting; + dnd_allow_exception_h dnd_allow_exception; + dnd_allow_exception_h temp; result = _dbus_init(); if (result != NOTIFICATION_ERROR_NONE) { @@ -1239,7 +1245,6 @@ int notification_ipc_request_load_system_setting(notification_system_setting_h * } result = _send_sync_noti(g_variant_new("(i)", uid), &reply, "load_system_setting"); - if (result == NOTIFICATION_ERROR_NONE) { reply_body = g_dbus_message_get_body(reply); g_variant_get(reply_body, "(v)", &setting_body); @@ -1250,10 +1255,34 @@ int notification_ipc_request_load_system_setting(notification_system_setting_h * g_object_unref(reply); return NOTIFICATION_ERROR_OUT_OF_MEMORY; } + notification_ipc_make_system_setting_from_gvariant(result_setting, setting_body); + result_setting->dnd_allow_exceptions = NULL; + + result = _send_sync_noti(g_variant_new("(i)", uid), &reply, "load_dnd_allow_exception"); + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(ia(v))", &count, &iter); + + dnd_allow_exception = (dnd_allow_exception_h)malloc(sizeof(struct notification_system_setting_dnd_allow_exception) * count); + if (dnd_allow_exception == NULL) { + g_object_unref(reply); + g_variant_iter_free(iter); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + } + + while (g_variant_iter_loop(iter, "(v)", &iter_body)) { + temp = dnd_allow_exception + index; + + notification_ipc_make_dnd_allow_exception_from_gvariant(temp, iter_body); + result_setting->dnd_allow_exceptions = g_list_append(result_setting->dnd_allow_exceptions, temp); + index++; + } + } *setting = result_setting; g_variant_unref(setting_body); + g_variant_iter_free(iter); } if (reply) @@ -1298,6 +1327,8 @@ int notification_ipc_update_system_setting(notification_system_setting_h system_ int result; GDBusMessage *reply = NULL; GVariant *body; + GList *list; + dnd_allow_exception_h dnd_allow_exception; result = _dbus_init(); if (result != NOTIFICATION_ERROR_NONE) { @@ -1319,6 +1350,19 @@ int notification_ipc_update_system_setting(notification_system_setting_h system_ result = _send_sync_noti(body, &reply, "update_noti_sys_setting"); + /* update dnd_allow_exceptions */ + list = g_list_first(system_setting->dnd_allow_exceptions); + + for (; list != NULL; list = list->next) { + dnd_allow_exception = list->data; + + body = g_variant_new("(iii)", + (int)(dnd_allow_exception->type), + (int)(dnd_allow_exception->value), + uid); + result = _send_sync_noti(body, &reply, "update_dnd_allow_exception"); + } + if (reply) g_object_unref(reply); @@ -1976,6 +2020,35 @@ EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_s return NOTIFICATION_ERROR_NONE; } +EXPORT_API GVariant *notification_ipc_make_gvariant_from_dnd_allow_exception(struct notification_system_setting_dnd_allow_exception *dnd_allow_exception) +{ + GVariant *body = NULL; + + body = g_variant_new("(ii)", + dnd_allow_exception->type, + dnd_allow_exception->value); + + return body; +} + +int notification_ipc_make_dnd_allow_exception_from_gvariant(struct notification_system_setting_dnd_allow_exception *dnd_allow_exception, GVariant *variant) +{ + int type; + int value; + + if (dnd_allow_exception == NULL) { + NOTIFICATION_ERR("invalid data"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + g_variant_get(variant, "(ii)", &type, &value); + + dnd_allow_exception->type = type; + dnd_allow_exception->value = value; + + return NOTIFICATION_ERROR_NONE; +} + static int _send_service_register(uid_t uid) { GDBusMessage *reply = NULL; diff --git a/src/notification_setting.c b/src/notification_setting.c index 0be8062..7d5b592 100755 --- a/src/notification_setting.c +++ b/src/notification_setting.c @@ -560,6 +560,9 @@ EXPORT_API int notification_system_setting_free_system_setting(notification_syst /* add codes to free all properties */ + if (system_setting->dnd_allow_exceptions != NULL) + g_list_free(system_setting->dnd_allow_exceptions); + SAFE_FREE(system_setting); return NOTIFICATION_ERROR_NONE; @@ -737,6 +740,75 @@ EXPORT_API int notification_system_setting_set_lock_screen_content(notification_ return NOTIFICATION_ERROR_NONE; } +static gint _dnd_allow_exception_compare(gconstpointer a, gconstpointer b) +{ + dnd_allow_exception_h dnd_allow_exception_data_a; + + if (a == NULL) + return -1; + + dnd_allow_exception_data_a = (dnd_allow_exception_h)a; + + if (dnd_allow_exception_data_a->type == (int)b) + return 0; + + return -1; +} + +EXPORT_API int notification_system_setting_get_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int *value) +{ + dnd_allow_exception_h dnd_allow_exception_data; + GList *list; + + if (system_setting == NULL) { + NOTIFICATION_ERR("Invalid parameter"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + list = g_list_find_custom(system_setting->dnd_allow_exceptions, (gconstpointer)type, _dnd_allow_exception_compare); + if (list) { + dnd_allow_exception_data = (dnd_allow_exception_h)list->data; + *value = dnd_allow_exception_data->value; + } else { + NOTIFICATION_ERR("Invalid parameter - type"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + return NOTIFICATION_ERROR_NONE; +} + +EXPORT_API int notification_system_setting_set_dnd_allow_exceptions(notification_system_setting_h system_setting, dnd_allow_exception_type_e type, int value) +{ + dnd_allow_exception_h dnd_allow_exception_data; + GList *list; + + if (system_setting == NULL) { + NOTIFICATION_ERR("Invalid parameter"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + list = g_list_first(system_setting->dnd_allow_exceptions); + + for (; list != NULL; list = list->next) { + dnd_allow_exception_data = (dnd_allow_exception_h)list->data; + if (dnd_allow_exception_data->type == type) { + dnd_allow_exception_data->value = value; + return NOTIFICATION_ERROR_NONE; + } + } + + dnd_allow_exception_data = (dnd_allow_exception_h)malloc(sizeof(struct notification_system_setting_dnd_allow_exception)); + if (dnd_allow_exception_data == NULL) + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + + dnd_allow_exception_data->type = type; + dnd_allow_exception_data->value = value; + + system_setting->dnd_allow_exceptions = g_list_append(system_setting->dnd_allow_exceptions, dnd_allow_exception_data); + + return NOTIFICATION_ERROR_NONE; +} + static gint _noti_dnd_cb_compare(gconstpointer a, gconstpointer b) { noti_dnd_cb_info_s *info = NULL; diff --git a/src/notification_setting_service.c b/src/notification_setting_service.c index 768250a..03a7d51 100644 --- a/src/notification_setting_service.c +++ b/src/notification_setting_service.c @@ -333,6 +333,7 @@ int noti_system_setting_load_system_setting(notification_system_setting_h *syste result_system_setting->dnd_end_hour = 0; result_system_setting->dnd_end_min = 0; result_system_setting->lock_screen_content_level = 0; + result_system_setting->dnd_allow_exceptions = NULL; } else { /* LCOV_EXCL_START */ col_index = column_count; @@ -345,6 +346,7 @@ int noti_system_setting_load_system_setting(notification_system_setting_h *syste _get_table_field_data_int(query_result, &(result_system_setting->dnd_end_hour), col_index++); _get_table_field_data_int(query_result, &(result_system_setting->dnd_end_min), col_index++); _get_table_field_data_int(query_result, (int *)&(result_system_setting->lock_screen_content_level), col_index++); + result_system_setting->dnd_allow_exceptions = NULL; /* LCOV_EXCL_STOP */ } @@ -655,3 +657,114 @@ out: return ret; } + +EXPORT_API int notification_system_setting_load_dnd_allow_exception(dnd_allow_exception_h *dnd_allow_exception, int *count, uid_t uid) +{ + int err = NOTIFICATION_ERROR_NONE; + int sql_return; + int row_count = 0; + int column_count = 0; + int col_index = 0; + int i; + char *sql_query = NULL; + char **query_result = NULL; + sqlite3 *local_db_handle = NULL; + dnd_allow_exception_h dnd_allow_exception_data = NULL; + + if (dnd_allow_exception == NULL) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); /* LCOV_EXCL_LINE */ + err = NOTIFICATION_ERROR_INVALID_PARAMETER; + goto out; + } + + sql_return = db_util_open(DBPATH, &local_db_handle, 0); + if (sql_return != SQLITE_OK || local_db_handle == NULL) { + NOTIFICATION_ERR("db_util_open failed [%d]", sql_return); /* LCOV_EXCL_LINE */ + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + sql_query = sqlite3_mprintf("SELECT type, value FROM %s WHERE uid = %d", + NOTIFICATION_DND_ALLOW_EXCEPTION, uid); + if (!sql_query) { + NOTIFICATION_ERR("fail to alloc query"); /* LCOV_EXCL_LINE */ + err = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto out; + } + + sql_return = sqlite3_get_table(local_db_handle, sql_query, &query_result, &row_count, &column_count, NULL); + if (sql_return != SQLITE_OK && sql_return != -1) { + NOTIFICATION_ERR("sqlite3_get_table failed [%d][%s]", sql_return, sql_query); /* LCOV_EXCL_LINE */ + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + if (!row_count) { + NOTIFICATION_DBG("No setting found..."); /* LCOV_EXCL_LINE */ + goto out; + } else { + dnd_allow_exception_data = (dnd_allow_exception_h)malloc(sizeof(struct notification_system_setting_dnd_allow_exception) * row_count); + if (dnd_allow_exception_data == NULL) { + NOTIFICATION_ERR("failed to malloc"); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + } + + col_index = column_count; + + for (i = 0; i < row_count; i++) { + _get_table_field_data_int(query_result, (int *)&(dnd_allow_exception_data[i].type), col_index++); + _get_table_field_data_int(query_result, (int *)&(dnd_allow_exception_data[i].value), col_index++); + } + } + + *dnd_allow_exception = dnd_allow_exception_data; + *count = row_count; + +out: + if (query_result) + sqlite3_free_table(query_result); + + if (sql_query) + sqlite3_free(sql_query); + + if (local_db_handle) { + sql_return = db_util_close(local_db_handle); + if (sql_return != SQLITE_OK) + NOTIFICATION_WARN("fail to db_util_close - [%d]", sql_return); /* LCOV_EXCL_LINE */ + } + + return err; +} + +EXPORT_API int notification_system_setting_update_dnd_allow_exception(int type, int value, uid_t uid) +{ + int ret = NOTIFICATION_ERROR_NONE; + int sqlret; + sqlite3 *db = NULL; + char *sqlbuf = NULL; + + sqlret = db_util_open(DBPATH, &db, 0); + if (sqlret != SQLITE_OK || db == NULL) { + NOTIFICATION_ERR("db_util_open failed [%s][%d]", DBPATH, sqlret); + return NOTIFICATION_ERROR_FROM_DB; + } + + sqlbuf = sqlite3_mprintf("UPDATE dnd_allow_exception SET value = %d WHERE type = %d AND uid = %d", value, type, uid); + if (!sqlbuf) { + NOTIFICATION_ERR("fail to alloc query"); + ret = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto return_close_db; + } + + ret = notification_db_exec(db, sqlbuf, NULL); + +return_close_db: + if (sqlbuf) + sqlite3_free(sqlbuf); + + sqlret = db_util_close(db); + if (sqlret != SQLITE_OK) + NOTIFICATION_WARN("fail to db_util_close - [%d]", sqlret); + + return ret; +} diff --git a/test-app/main.c b/test-app/main.c index 8c93e97..c6fd92f 100755 --- a/test-app/main.c +++ b/test-app/main.c @@ -727,6 +727,8 @@ static int testapp_test_update_system_setting() bool dnd_schedule_enabled; lock_screen_content_level_e lock_screen_content_level = SHOW_ALL_CONTENT; notification_system_setting_h system_setting = NULL; + dnd_allow_exception_type_e dnd_allow_exception_type = NOTIFICATION_DND_ALLOWED_CALLS; + int dnd_allowed_calls_value; err = notification_system_setting_load_system_setting(&system_setting); @@ -754,8 +756,13 @@ static int testapp_test_update_system_setting() testapp_print("lock_screen_content_level [%d]\n", lock_screen_content_level); lock_screen_content_level = !lock_screen_content_level; notification_system_setting_set_lock_screen_content(system_setting, lock_screen_content_level); - err = notification_system_setting_update_system_setting(system_setting); + notification_system_setting_get_dnd_allow_exceptions(system_setting, dnd_allow_exception_type, &dnd_allowed_calls_value); + testapp_print("dnd_allowed_calls_value [%d]\n", dnd_allowed_calls_value); + dnd_allowed_calls_value = !dnd_allowed_calls_value; + notification_system_setting_set_dnd_allow_exceptions(system_setting, dnd_allow_exception_type, dnd_allowed_calls_value); + + err = notification_system_setting_update_system_setting(system_setting); if (err != NOTIFICATION_ERROR_NONE || system_setting == NULL) { testapp_print("notification_system_setting_update_system_setting failed [%d]\n", err); goto out; -- 2.7.4