Add apis for dnd_allow_exception 46/87646/12
authorMyungki Lee <mk5004.lee@samsung.com>
Mon, 19 Sep 2016 10:10:19 +0000 (19:10 +0900)
committerMyungKi Lee <mk5004.lee@samsung.com>
Tue, 20 Sep 2016 02:35:34 +0000 (19:35 -0700)
- notification_system_setting_set_dnd_allow_exceptions()
  notification_system_setting_get_dnd_allow_exceptions()

Change-Id: I9e2fda4ca1b705383a7d74dea5198eef99c19063
Signed-off-by: Myungki Lee <mk5004.lee@samsung.com>
include/notification_ipc.h
include/notification_private.h
include/notification_setting_internal.h
include/notification_setting_service.h
src/notification_db.c
src/notification_ipc.c
src/notification_setting.c
src/notification_setting_service.c
test-app/main.c

index db14a28..dcde048 100755 (executable)
@@ -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
 }
index f895b9b..167b1c5 100644 (file)
@@ -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;
index 3011cae..cbe0cae 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <sys/types.h>
 #include <stdbool.h>
+#include <glib.h>
 #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 <notification_setting_internal.h>
+...
+{
+       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 <notification_setting_internal.h>
+...
+{
+       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
index 2ec8f45..592cff0 100644 (file)
@@ -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
index 58b5151..5c9c414 100755 (executable)
@@ -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, \
index 546f9a1..1f8d9ed 100755 (executable)
@@ -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;
index 0be8062..7d5b592 100755 (executable)
@@ -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;
index 768250a..03a7d51 100644 (file)
@@ -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;
+}
index 8c93e97..c6fd92f 100755 (executable)
@@ -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;