Add internal api for notification system dnd schedule changed callback 01/80501/13 accepted/tizen/common/20160809.183903 accepted/tizen/ivi/20160809.232602 accepted/tizen/mobile/20160809.232332 accepted/tizen/tv/20160809.232451 accepted/tizen/wearable/20160809.232657 submit/tizen/20160809.011327 submit/tizen/20160809.051427
authorseungha.son <seungha.son@samsung.com>
Mon, 18 Jul 2016 10:02:58 +0000 (19:02 +0900)
committerseungha.son <seungha.son@samsung.com>
Thu, 4 Aug 2016 09:48:18 +0000 (18:48 +0900)
Signed-off-by: seungha.son <seungha.son@samsung.com>
Change-Id: I5f3c59388d7ce2b834546930ef11e6d5a3fa72a8

include/notification_private.h
include/notification_setting_internal.h
include/notification_setting_service.h
src/notification_ipc.c
src/notification_setting.c
src/notification_setting_service.c

index 935fdf8..d9a7167 100644 (file)
@@ -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__ */
index c22019b..0f4fb7e 100644 (file)
 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;
index 2181044..6de7bab 100644 (file)
@@ -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
index 236608d..ba91a6c 100755 (executable)
@@ -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 */
 
index e7acafb..5205872 100755 (executable)
 
 #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());
+}
index be6438a..61c3a0a 100644 (file)
@@ -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;
+}