diff options
-rw-r--r-- | include/notification_private.h | 2 | ||||
-rw-r--r-- | include/notification_setting_internal.h | 87 | ||||
-rw-r--r-- | include/notification_setting_service.h | 2 | ||||
-rwxr-xr-x | src/notification_ipc.c | 15 | ||||
-rwxr-xr-x | src/notification_setting.c | 142 | ||||
-rw-r--r-- | src/notification_setting_service.c | 57 |
6 files changed, 302 insertions, 3 deletions
diff --git a/include/notification_private.h b/include/notification_private.h index 935fdf8..d9a7167 100644 --- a/include/notification_private.h +++ b/include/notification_private.h @@ -146,7 +146,7 @@ typedef enum notification_data_type { } notification_data_type_e; void notification_call_changed_cb_for_uid(notification_op *op_list, int op_num, uid_t uid); - +void notification_call_dnd_changed_cb_for_uid(int do_not_disturb, uid_t uid); char *notification_get_pkgname_by_pid(void); #endif /* __NOTIFICATION_PRIVATE_H__ */ diff --git a/include/notification_setting_internal.h b/include/notification_setting_internal.h index c22019b..0f4fb7e 100644 --- a/include/notification_setting_internal.h +++ b/include/notification_setting_internal.h @@ -26,6 +26,11 @@ extern "C" { #endif +/* + * The prototype of handler that 'Do not disturb' mode set schdule changed alarm. + */ +typedef void (*dnd_changed_cb)(void *user_data, int do_not_disturb); + /** * @brief Enumeration for Week Flag, the days of the week. * @since_tizen 3.0 @@ -122,6 +127,88 @@ int notification_system_setting_dnd_schedule_set_end_time(notification_system_se int notification_system_setting_set_lock_screen_content(notification_system_setting_h system_setting, lock_screen_content_level_e level); int notification_system_setting_get_lock_screen_content(notification_system_setting_h system_setting, lock_screen_content_level_e *level); + + +/* + * @internal + * @brief Registers a callback for 'Do not disturb' mode setting schedule is start or end. + * @since_tizen 3.0 + * @param[in] callback The callback function + * @param[in] user_data The user data + * @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_IO_ERROR I/O Error + * @retval #NOTIFICATION_ERROR_OUT_OF_MEMORY out of memory + * @par sample code: + * @code +#include <notification_setting_internal.h> +... + +static void changed_cb(void *user_data, int do_not_disturb) +{ + ... +} + +... +{ + int noti_err = 0; + + ... + + noti_err = notification_register_system_setting_dnd_changed_cb(changed_cb, NULL); + if(noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + + return 0; + +} + * @endcode + */ +int notification_register_system_setting_dnd_changed_cb(dnd_changed_cb callback, void *user_data); +int notification_register_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, void *user_data, uid_t uid); + +/* + * @internal + * @brief Unregisters a callback for 'Do not disturb' mode setting schedule is start or end. + * @since_tizen 3.0 + * @param[in] callback The callback function + * @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 <notification_setting_internal.h> +... + +static void changed_cb(void *user_data, int do_not_disturb) +{ + ... +} + +... +{ + int noti_err = 0; + + ... + + noti_err = notification_unregister_system_setting_dnd_changed_cb(changed_cb); + if(noti_err != NOTIFICATION_ERROR_NONE) { + return; + } + + return 0; + +} + * @endcode + */ +int notification_unregister_system_setting_dnd_changed_cb(dnd_changed_cb callback); +int notification_unregister_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, uid_t uid); + + /* OLD IMPLEMENTATION */ int notification_setting_property_set(const char *pkgname, const char *property, const char *value) NOTIFICATION_DEPRECATED_API; int notification_setting_property_get(const char *pkgname, const char *property, char **value) NOTIFICATION_DEPRECATED_API; diff --git a/include/notification_setting_service.h b/include/notification_setting_service.h index 2181044..6de7bab 100644 --- a/include/notification_setting_service.h +++ b/include/notification_setting_service.h @@ -38,7 +38,7 @@ int notification_setting_db_update_do_not_disturb(int do_not_disturb, uid_t uid) int noti_setting_service_get_setting_by_package_name(const char *package_name, notification_setting_h *setting, uid_t uid); int noti_setting_get_setting_array(notification_setting_h *setting_array, int *count, uid_t uid); 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); #ifdef __cplusplus } #endif diff --git a/src/notification_ipc.c b/src/notification_ipc.c index 236608d..ba91a6c 100755 --- a/src/notification_ipc.c +++ b/src/notification_ipc.c @@ -470,6 +470,19 @@ static void _delete_multiple_notify(GVariant *parameters) /* LCOV_EXCL_STOP */ /* LCOV_EXCL_START */ +static void _change_dnd_notify(GVariant *parameters) +{ + int do_not_disturb; + uid_t uid; + + g_variant_get(parameters, "(ii)", &do_not_disturb, &uid); + NOTIFICATION_DBG("do_not_disturb[%d], uid[%d]", do_not_disturb, uid); + + notification_call_dnd_changed_cb_for_uid(do_not_disturb, uid); +} +/* LCOV_EXCL_STOP */ + +/* LCOV_EXCL_START */ static void _handle_noti_notify(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -491,6 +504,8 @@ static void _handle_noti_notify(GDBusConnection *connection, _delete_multiple_notify(parameters); else if (g_strcmp0(signal_name, "refresh_noti_notify") == 0) _refresh_noti_notify(parameters); + else if (g_strcmp0(signal_name, "change_dnd_notify") == 0) + _change_dnd_notify(parameters); } /* LCOV_EXCL_STOP */ diff --git a/src/notification_setting.c b/src/notification_setting.c index e7acafb..5205872 100755 --- a/src/notification_setting.c +++ b/src/notification_setting.c @@ -35,11 +35,20 @@ #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification" +typedef struct _noti_dnd_cb_info noti_dnd_cb_info_s; + typedef struct { uid_t uid; sqlite3 *db; } setting_local_info; +struct _noti_dnd_cb_info { + dnd_changed_cb callback; + void *user_data; +}; + +static GHashTable *_noti_dnd_cb_hash = NULL; + EXPORT_API int notification_setting_get_setting_array_for_uid(notification_setting_h *setting_array, int *count, uid_t uid) { if (setting_array == NULL || count == NULL) { @@ -54,7 +63,6 @@ EXPORT_API int notification_setting_get_setting_array(notification_setting_h *se { return notification_setting_get_setting_array_for_uid(setting_array, count, getuid()); } - EXPORT_API int notification_setting_get_setting_by_package_name_for_uid(const char *package_name, notification_setting_h *setting, uid_t uid) { if (package_name == NULL || setting == NULL) { @@ -684,3 +692,135 @@ EXPORT_API int notification_system_setting_set_lock_screen_content(notification_ return NOTIFICATION_ERROR_NONE; } + +static gint _noti_dnd_cb_compare(gconstpointer a, gconstpointer b) +{ + noti_dnd_cb_info_s *info = NULL; + + if (a == NULL) + return -1; + + info = (noti_dnd_cb_info_s *)a; + if (info->callback == b) + return 0; + + return 1; +} + +void notification_call_dnd_changed_cb_for_uid(int do_not_disturb, uid_t uid) +{ + GList *noti_dnd_cb_list = NULL; + noti_dnd_cb_info_s *dnd_data = NULL; + + if (_noti_dnd_cb_hash == NULL) + return; + + noti_dnd_cb_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid)); + if (noti_dnd_cb_list == NULL) { + NOTIFICATION_ERR("Invalide data"); + return; + } + + noti_dnd_cb_list = g_list_first(noti_dnd_cb_list); + + for (; noti_dnd_cb_list != NULL; noti_dnd_cb_list = noti_dnd_cb_list->next) { + dnd_data = noti_dnd_cb_list->data; + + if (dnd_data != NULL && dnd_data->callback != NULL) + dnd_data->callback(dnd_data->user_data, do_not_disturb); + } +} + +EXPORT_API int notification_register_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, void *user_data, uid_t uid) +{ + GList *noti_dnd_list = NULL; + GList *noti_dnd_found_list = NULL; + noti_dnd_cb_info_s *dnd_data = NULL; + + if (callback == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + if (notification_ipc_monitor_init(uid) != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("notification_ipc_monitor_init error"); + return NOTIFICATION_ERROR_IO_ERROR; + } + if (_noti_dnd_cb_hash == NULL) + _noti_dnd_cb_hash = g_hash_table_new(g_direct_hash, g_direct_equal); + + dnd_data = (noti_dnd_cb_info_s *)malloc(sizeof(noti_dnd_cb_info_s)); + if (dnd_data == NULL) + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + + dnd_data->callback = callback; + dnd_data->user_data = user_data; + + noti_dnd_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid)); + + if (noti_dnd_list == NULL) { + noti_dnd_list = g_list_append(noti_dnd_list, dnd_data); + g_hash_table_insert(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid), noti_dnd_list); + } else { + noti_dnd_found_list = g_list_find_custom(noti_dnd_list, (gconstpointer)callback, + _noti_dnd_cb_compare); + if (noti_dnd_found_list) { + NOTIFICATION_ERR("Already existing callback"); + free(dnd_data); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } else { + noti_dnd_list = g_list_append(noti_dnd_list, dnd_data); + } + } + + return NOTIFICATION_ERROR_NONE; +} + +EXPORT_API int notification_register_system_setting_dnd_changed_cb(dnd_changed_cb callback, void *user_data) +{ + return notification_register_system_setting_dnd_changed_cb_for_uid(callback, user_data, getuid()); +} + +EXPORT_API int notification_unregister_system_setting_dnd_changed_cb_for_uid(dnd_changed_cb callback, uid_t uid) +{ + GList *noti_dnd_cb_list = NULL; + GList *noti_dnd_del_list = NULL; + noti_dnd_cb_info_s *dnd_data = NULL; + + if (callback == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + if (_noti_dnd_cb_hash == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + noti_dnd_cb_list = (GList *)g_hash_table_lookup(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid)); + + if (noti_dnd_cb_list == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + noti_dnd_del_list = g_list_find_custom(noti_dnd_cb_list, (gconstpointer)callback, + _noti_dnd_cb_compare); + + if (noti_dnd_del_list) { + dnd_data = g_list_nth_data(noti_dnd_del_list, 0); + noti_dnd_cb_list = g_list_delete_link(noti_dnd_cb_list, noti_dnd_del_list); + free(dnd_data); + } else { + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + if (noti_dnd_cb_list == NULL) { + g_hash_table_steal(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid)); + } else { + noti_dnd_cb_list = g_list_first(noti_dnd_cb_list); + g_hash_table_replace(_noti_dnd_cb_hash, GUINT_TO_POINTER(uid), noti_dnd_cb_list); + } + + if (g_hash_table_size(_noti_dnd_cb_hash) == 0) + notification_ipc_monitor_fini(); + + return NOTIFICATION_ERROR_NONE; +} + +EXPORT_API int notification_unregister_system_setting_dnd_changed_cb(dnd_changed_cb callback) +{ + return notification_unregister_system_setting_dnd_changed_cb_for_uid(callback, getuid()); +} diff --git a/src/notification_setting_service.c b/src/notification_setting_service.c index be6438a..61c3a0a 100644 --- a/src/notification_setting_service.c +++ b/src/notification_setting_service.c @@ -510,4 +510,61 @@ return_close_db: } /* LCOV_EXCL_STOP */ +EXPORT_API int notification_system_setting_get_dnd_schedule_enabled_uid(uid_t **uids, int *count) +{ + int ret, i; + int row_count = 0; + int column_count = 0; + int column_index = 0; + char *query = NULL; + char **query_result = NULL; + sqlite3 *db = NULL; + uid_t *result_uids; + + db = notification_db_open(DBPATH); + if (db == NULL) + return get_last_result(); + + query = sqlite3_mprintf("SELECT uid FROM %s WHERE dnd_schedule_enabled = 1", + NOTIFICATION_SYSTEM_SETTING_DB_TABLE); + if (query == NULL) { + ret = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto err; + } + + ret = sqlite3_get_table(db, query, &query_result, &row_count, &column_count, NULL); + if (ret != SQLITE_OK && ret != -1) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_FROM_DB failed [%d][%s]", ret, query); /* LCOV_EXCL_LINE */ + ret = NOTIFICATION_ERROR_FROM_DB; + goto err; + } + + if (row_count == 0) { + NOTIFICATION_DBG("No enabled do_not_disturb user"); + ret = NOTIFICATION_ERROR_NONE; + goto err; + } + + if (!(result_uids = (uid_t *)malloc(sizeof(int) * row_count))) { + NOTIFICATION_ERR("Memory allocation fail"); + ret = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto err; + } + + column_index = column_count; + for (i = 0; i < row_count; i++) + _get_table_field_data_int(query_result, (int *)&(result_uids[i]), column_index++); + + *uids = result_uids; + *count = row_count; +err: + if (query_result) + sqlite3_free_table(query_result); + if (query) + sqlite3_free(query); + if (db) + notification_db_close(&db); + + return ret; +} |