diff options
author | Hyunho Kang <hhstark.kang@samsung.com> | 2016-01-20 16:13:18 +0900 |
---|---|---|
committer | Hyunho Kang <hhstark.kang@samsung.com> | 2016-02-29 20:04:48 +0900 |
commit | 4bbfcfbf4b61878d99d010e7af9aa04c9ff0f430 (patch) | |
tree | bdb7d927001613bf24edb6a00003fdefb210d3c7 | |
parent | 1ef0da7a24fdcadb1ddb08440c54050764bb32b2 (diff) | |
download | notification-tizen_3.0_dbus.tar.gz notification-tizen_3.0_dbus.tar.bz2 notification-tizen_3.0_dbus.zip |
Using gdbus for IPC instead of com-core packagetizen_3.0_dbus
Change-Id: Ib9b06e8deeaef18f8319a5765797b1b96b7bc195
Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com>
Signed-off-by: jusung son <jusung07.son@samsung.com>
-rwxr-xr-x[-rw-r--r--] | CMakeLists.txt | 3 | ||||
-rw-r--r-- | include/notification_error.h | 2 | ||||
-rw-r--r-- | include/notification_internal.h | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | include/notification_ipc.h | 42 | ||||
-rw-r--r-- | include/notification_permission.h | 29 | ||||
-rw-r--r-- | include/notification_private.h | 52 | ||||
-rw-r--r-- | include/notification_setting_service.h | 4 | ||||
-rw-r--r-- | include/notification_type.h | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | packaging/notification.spec | 2 | ||||
-rwxr-xr-x | src/notification.c | 49 | ||||
-rw-r--r-- | src/notification_error.c | 46 | ||||
-rwxr-xr-x | src/notification_internal.c | 43 | ||||
-rwxr-xr-x | src/notification_ipc.c | 2599 | ||||
-rwxr-xr-x | src/notification_list.c | 12 | ||||
-rwxr-xr-x | src/notification_noti.c | 38 | ||||
-rwxr-xr-x | src/notification_permission.c | 76 | ||||
-rwxr-xr-x | src/notification_setting.c | 307 | ||||
-rw-r--r-- | src/notification_setting_service.c | 348 |
18 files changed, 2090 insertions, 1567 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 87da206..d25fd24 100644..100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,9 @@ SET(SRCS ./src/notification_status.c ./src/notification_ipc.c ./src/notification_setting.c + ./src/notification_setting_service.c ./src/notification_internal.c + ./src/notification_error.c ./src/notification_old.c) SET(HEADERS-DEVEL ./include/notification.h @@ -64,6 +66,7 @@ pkg_check_modules(pkgs REQUIRED ecore eina libtzplatform-config + gio-2.0 ) FOREACH(flag ${pkgs_CFLAGS}) diff --git a/include/notification_error.h b/include/notification_error.h index 42c3897..7670e8e 100644 --- a/include/notification_error.h +++ b/include/notification_error.h @@ -51,7 +51,7 @@ typedef enum _notification_error { NOTIFICATION_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented (@b Since: 2.4) */ } notification_error_e; -/** +/** * @} */ diff --git a/include/notification_internal.h b/include/notification_internal.h index 4c55040..c0fa4f3 100644 --- a/include/notification_internal.h +++ b/include/notification_internal.h @@ -21,7 +21,7 @@ #ifndef __NOTIFICATION_INTERNAL_H__ #define __NOTIFICATION_INTERNAL_H__ - +#include <glib.h> #include <notification_error.h> #include <notification_type.h> #include <notification_list.h> @@ -36,6 +36,8 @@ extern "C" { */ #define NOTIFICATION_DISPLAY_APP_HEADS_UP NOTIFICATION_DISPLAY_APP_ACTIVE /* To avoid build error */ +#define NOTIFICATION_ERROR (notification_error_quark ()) +GQuark notification_error_quark(void); /** * @brief This function add deferred task. the registered task will be executed when notification service become ready diff --git a/include/notification_ipc.h b/include/notification_ipc.h index 26e0650..66d567d 100644..100755 --- a/include/notification_ipc.h +++ b/include/notification_ipc.h @@ -22,45 +22,55 @@ #ifndef __NOTIFICATION_IPC_H__ #define __NOTIFICATION_IPC_H__ +#include <gio/gio.h> #include <notification.h> #include <notification_setting.h> #include <notification_setting_internal.h> - -#define NOTIFICATION_ADDR "/tmp/.notification.service" -#define NOTIFICATION_DEL_PACKET_UNIT 10 +#include <notification_list.h> #ifdef __cplusplus extern "C" { #endif -struct packet; +GVariant *notification_ipc_make_gvariant_from_noti(notification_h noti); +int notification_ipc_make_noti_from_gvariant(notification_h noti, GVariant *variant); -int notification_ipc_monitor_init(void); -int notification_ipc_monitor_fini(void); +GVariant *notification_ipc_make_gvariant_from_setting(struct notification_setting *noti_setting); +int notification_ipc_make_setting_from_gvariant(struct notification_setting *noti_setting, + GVariant *variant); -int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet); -struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type); -struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet); +GVariant *notification_ipc_make_gvariant_from_system_setting(struct notification_system_setting *noti_setting); +int notification_ipc_make_system_setting_from_gvariant(struct notification_system_setting *noti_setting, + GVariant *variant); +int notification_dbus_init(); +int notification_ipc_monitor_init(void); +int notification_ipc_monitor_fini(void); +int notification_ipc_is_master_ready(void); +int notification_ipc_add_deffered_task(void (*deferred_task_cb)(void *data), void *user_data); +int notification_ipc_del_deffered_task(void (*deferred_task_cb)(void *data)); int notification_ipc_request_insert(notification_h noti, int *priv_id); int notification_ipc_request_update(notification_h noti); int notification_ipc_request_update_async(notification_h noti, void (*result_cb)(int priv_id, int result, void *data), void *user_data); int notification_ipc_request_refresh(void); -int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id); int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname); - -int notification_ipc_is_master_ready(void); -int notification_ipc_add_deffered_task(void (*deferred_task_cb)(void *data), void *user_data); -int notification_ipc_del_deffered_task(void (*deferred_task_cb)(void *data)); - +int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id); int notification_ipc_update_setting(notification_setting_h setting); int notification_ipc_update_system_setting(notification_system_setting_h system_setting); int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value); int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value); - int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag); +int notification_ipc_request_load_noti_grouping_list(notification_type_e type, int count, + notification_list_h *list); +int notification_ipc_request_get_setting_array(notification_setting_h *setting_array, int *count); +int notification_ipc_request_get_setting_by_package_name( + const char *package_name, notification_setting_h *setting); +int notification_ipc_request_load_system_setting(notification_system_setting_h *setting); +int notification_ipc_request_get_count(notification_type_e type, const char *pkgname, int group_id, int priv_id, int *count); +int notification_ipc_request_load_noti_by_priv_id(notification_h noti, const char *pkgname, int priv_id); +int notification_ipc_request_load_noti_detail_list(const char *pkgname, int group_id, int priv_id, int count, notification_list_h *list); #ifdef __cplusplus } diff --git a/include/notification_permission.h b/include/notification_permission.h new file mode 100644 index 0000000..9e82601 --- /dev/null +++ b/include/notification_permission.h @@ -0,0 +1,29 @@ +/* + * libnotification + * + * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __NOTIFICATION_PERMISSION_H__ +#define __NOTIFICATION_PERMISSION_H__ + +#ifndef EXPORT_API +#define EXPORT_API __attribute__ ((visibility("default"))) +#endif + +int notification_check_permission(); + +#endif /* __NOTIFICATION_PERMISSION_H__ */ diff --git a/include/notification_private.h b/include/notification_private.h index 2e0e96a..1e98d38 100644 --- a/include/notification_private.h +++ b/include/notification_private.h @@ -105,6 +105,58 @@ struct notification_system_setting { int visibility_class; }; +typedef enum notification_data_type { + NOTIFICATION_DATA_TYPE_NOTI_TYPE = 1, + NOTIFICATION_DATA_TYPE_LAYOUT, + NOTIFICATION_DATA_TYPE_GROUP_ID, + NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, + NOTIFICATION_DATA_TYPE_PRIV_ID, + NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, + NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, + NOTIFICATION_DATA_TYPE_ARGS, + NOTIFICATION_DATA_TYPE_GROUP_ARGS, + NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, + NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, + NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, + NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, + NOTIFICATION_DATA_TYPE_BUTTON1_EVENT, + NOTIFICATION_DATA_TYPE_BUTTON2_EVENT, + NOTIFICATION_DATA_TYPE_BUTTON3_EVENT, + NOTIFICATION_DATA_TYPE_BUTTON4_EVENT, + NOTIFICATION_DATA_TYPE_BUTTON5_EVENT, + NOTIFICATION_DATA_TYPE_BUTTON6_EVENT, + NOTIFICATION_DATA_TYPE_ICON_EVENT, + NOTIFICATION_DATA_TYPE_THUMBNAIL_EVENT, + NOTIFICATION_DATA_TYPE_DOMAIN, + NOTIFICATION_DATA_TYPE_DIR, + NOTIFICATION_DATA_TYPE_TEXT, + NOTIFICATION_DATA_TYPE_KEY, + NOTIFICATION_DATA_TYPE_FORMAT_ARGS, + NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, + NOTIFICATION_DATA_TYPE_IMAGE_PATH, + NOTIFICATION_DATA_TYPE_SOUND_TYPE, + NOTIFICATION_DATA_TYPE_SOUND_PATH, + NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, + NOTIFICATION_DATA_TYPE_VIBRATION_PATH, + NOTIFICATION_DATA_TYPE_LED_OPERATION, + NOTIFICATION_DATA_TYPE_LED_ARGB, + NOTIFICATION_DATA_TYPE_LED_ON_MS, + NOTIFICATION_DATA_TYPE_LED_OFF_MS, + NOTIFICATION_DATA_TYPE_TIME, + NOTIFICATION_DATA_TYPE_INSERT_TIME, + NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, + NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, + NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, + NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, + NOTIFICATION_DATA_TYPE_APP_ICON_PATH, + NOTIFICATION_DATA_TYPE_APP_NAME, + NOTIFICATION_DATA_TYPE_TEMP_TITLE, + NOTIFICATION_DATA_TYPE_TEMP_CONTENT, + NOTIFICATION_DATA_TYPE_TAG, + NOTIFICATION_DATA_TYPE_ONGOING_FLAG, + NOTIFICATION_DATA_TYPE_AUTO_REMOVE, +} notification_data_type_e; + void notification_call_changed_cb(notification_op *op_list, int op_num); char *notification_get_pkgname_by_pid(void); diff --git a/include/notification_setting_service.h b/include/notification_setting_service.h index f8b0fd4..63f37c4 100644 --- a/include/notification_setting_service.h +++ b/include/notification_setting_service.h @@ -34,6 +34,10 @@ int notification_setting_db_get(const char *pkgname, const char *property, char int notification_setting_db_update(const char *package_name, int allow_to_notify, int do_not_disturb_except, int visibility_class); int notification_setting_db_update_system_setting(int do_not_disturb, int visibility_class); +int noti_setting_service_get_setting_by_package_name(const char *package_name, notification_setting_h *setting); +int noti_setting_get_setting_array(notification_setting_h *setting_array, int *count); +int noti_system_setting_load_system_setting(notification_system_setting_h *system_setting); + #ifdef __cplusplus } #endif diff --git a/include/notification_type.h b/include/notification_type.h index 3b3d154..da0d653 100644 --- a/include/notification_type.h +++ b/include/notification_type.h @@ -426,6 +426,7 @@ typedef enum notification_permission_type { NOTIFICATION_PERMISSION_TYPE_DELETE = 1, NOTIFICATION_PERMISSION_TYPE_UPDATE = 2, } notification_permission_type_e; + /** * @} */ diff --git a/packaging/notification.spec b/packaging/notification.spec index b1d9447..87356a4 100644..100755 --- a/packaging/notification.spec +++ b/packaging/notification.spec @@ -27,6 +27,8 @@ BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(glib-2.0) BuildRequires: cmake Requires(post): /sbin/ldconfig diff --git a/src/notification.c b/src/notification.c index 78fa01f..7eb7606 100755 --- a/src/notification.c +++ b/src/notification.c @@ -587,11 +587,11 @@ EXPORT_API int notification_get_text(notification_h noti, if (ret_variable_int == NOTIFICATION_COUNT_POS_LEFT) { - notification_noti_get_count(noti->type, - noti->caller_pkgname, - noti->group_id, - noti->priv_id, - &ret_variable_int); + notification_get_count(noti->type, + noti->caller_pkgname, + noti->group_id, + noti->priv_id, + &ret_variable_int); snprintf(buf_str, sizeof(buf_str), "%d ", ret_variable_int); @@ -628,12 +628,11 @@ EXPORT_API int notification_get_text(notification_h noti, if (ret_var_type == NOTIFICATION_VARIABLE_TYPE_COUNT) { /* Get notification count */ - notification_noti_get_count - (noti->type, - noti->caller_pkgname, - noti->group_id, - noti->priv_id, - &ret_variable_int); + notification_get_count(noti->type, + noti->caller_pkgname, + noti->group_id, + noti->priv_id, + &ret_variable_int); } else { /* Get var Value */ snprintf(buf_key, @@ -725,12 +724,11 @@ EXPORT_API int notification_get_text(notification_h noti, if (ret_var_type == NOTIFICATION_VARIABLE_TYPE_COUNT) { /* Get notification count */ - notification_noti_get_count - (noti->type, - noti->caller_pkgname, - noti->group_id, - noti->priv_id, - &ret_variable_int); + notification_get_count(noti->type, + noti->caller_pkgname, + noti->group_id, + noti->priv_id, + &ret_variable_int); } else { /* Get var Value */ snprintf(buf_key, @@ -820,12 +818,11 @@ EXPORT_API int notification_get_text(notification_h noti, if (ret_variable_int == NOTIFICATION_COUNT_POS_RIGHT) { - notification_noti_get_count - (noti->type, - noti->caller_pkgname, - noti->group_id, - noti->priv_id, - &ret_variable_int); + notification_get_count(noti->type, + noti->caller_pkgname, + noti->group_id, + noti->priv_id, + &ret_variable_int); snprintf(buf_str, sizeof(buf_str), " %d", ret_variable_int); @@ -1689,7 +1686,7 @@ EXPORT_API notification_h notification_load_by_tag(const char *tag) return NULL; } - noti = (notification_h) calloc(1, sizeof(struct _notification)); + noti = (notification_h)calloc(1, sizeof(struct _notification)); if (noti == NULL) { NOTIFICATION_ERR("Failed to alloc a new notification"); set_last_result(NOTIFICATION_ERROR_OUT_OF_MEMORY); @@ -1698,12 +1695,10 @@ EXPORT_API notification_h notification_load_by_tag(const char *tag) return NULL; } - ret = notification_noti_get_by_tag(noti, caller_pkgname, (char*)tag); - + ret = notification_ipc_request_load_noti_by_tag(noti, caller_pkgname, (char*)tag); free(caller_pkgname); set_last_result(ret); - if (ret != NOTIFICATION_ERROR_NONE) { notification_free(noti); return NULL; diff --git a/src/notification_error.c b/src/notification_error.c new file mode 100644 index 0000000..1ed2317 --- /dev/null +++ b/src/notification_error.c @@ -0,0 +1,46 @@ +/* + * libnotification + * + * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <gio/gio.h> +#include "notification_error.h" + +static const GDBusErrorEntry dbus_error_entries[] = +{ + {NOTIFICATION_ERROR_INVALID_PARAMETER, "org.freedesktop.Notification.Error.INVALID_PARAMETER"}, + {NOTIFICATION_ERROR_OUT_OF_MEMORY, "org.freedesktop.Notification.Error.OUT_OF_MEMORY"}, + {NOTIFICATION_ERROR_IO_ERROR, "org.freedesktop.Notification.Error.IO_ERROR"}, + {NOTIFICATION_ERROR_PERMISSION_DENIED, "org.freedesktop.Notification.Error.PERMISSION_DENIED"}, + {NOTIFICATION_ERROR_FROM_DB, "org.freedesktop.Notification.Error.FROM_DB"}, + {NOTIFICATION_ERROR_ALREADY_EXIST_ID, "org.freedesktop.Notification.Error.ALREADY_EXIST_ID"}, + {NOTIFICATION_ERROR_FROM_DBUS, "org.freedesktop.Notification.Error.FROM_DBUS"}, + {NOTIFICATION_ERROR_NOT_EXIST_ID, "org.freedesktop.Notification.Error.NOT_EXIST_ID"}, + {NOTIFICATION_ERROR_SERVICE_NOT_READY, "org.freedesktop.Notification.Error.SERVICE_NOT_READY"}, + {NOTIFICATION_ERROR_INVALID_OPERATION, "org.freedesktop.Notification.Error.INVALID_OPERATION"}, +}; + +EXPORT_API GQuark notification_error_quark (void) +{ + static volatile gsize quark_volatile = 0; + g_dbus_error_register_error_domain ("notification-error-quark", + &quark_volatile, + dbus_error_entries, + G_N_ELEMENTS(dbus_error_entries)); + return (GQuark) quark_volatile; +} + diff --git a/src/notification_internal.c b/src/notification_internal.c index c14c68c..1ef0dac 100755 --- a/src/notification_internal.c +++ b/src/notification_internal.c @@ -532,17 +532,11 @@ EXPORT_API int notification_delete_group_by_group_id(const char *pkgname, caller_pkgname = strdup(pkgname); ret = notification_ipc_request_delete_multiple(type, caller_pkgname); - if (ret != NOTIFICATION_ERROR_NONE) { - if (caller_pkgname) - free(caller_pkgname); - - return ret; - } if (caller_pkgname) free(caller_pkgname); - return NOTIFICATION_ERROR_NONE; + return ret; } EXPORT_API int notification_delete_group_by_priv_id(const char *pkgname, @@ -558,17 +552,11 @@ EXPORT_API int notification_delete_group_by_priv_id(const char *pkgname, caller_pkgname = strdup(pkgname); ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id); - if (ret != NOTIFICATION_ERROR_NONE) { - if (caller_pkgname) - free(caller_pkgname); - - return ret; - } if (caller_pkgname) free(caller_pkgname); - return NOTIFICATION_ERROR_NONE; + return ret; } EXPORT_API int notification_get_count(notification_type_e type, @@ -577,20 +565,27 @@ EXPORT_API int notification_get_count(notification_type_e type, int priv_id, int *count) { int ret = 0; - int noti_count = 0; + char *caller_pkgname = NULL; if (count == NULL) return NOTIFICATION_ERROR_INVALID_PARAMETER; - ret = - notification_noti_get_count(type, pkgname, group_id, priv_id, - ¬i_count); - if (ret != NOTIFICATION_ERROR_NONE) - return ret; + if (pkgname == NULL) + caller_pkgname = notification_get_pkgname_by_pid(); + else + caller_pkgname = strdup(pkgname); - *count = noti_count; + ret = notification_ipc_request_get_count( + type, + caller_pkgname, + group_id, + priv_id, + count); - return NOTIFICATION_ERROR_NONE; + if (caller_pkgname) + free(caller_pkgname); + + return ret; } EXPORT_API int notification_clear(notification_type_e type) @@ -825,13 +820,13 @@ EXPORT_API notification_h notification_load(char *pkgname, int ret = 0; notification_h noti = NULL; - noti = (notification_h) calloc(1, sizeof(struct _notification)); + noti = (notification_h)calloc(1, sizeof(struct _notification)); if (noti == NULL) { NOTIFICATION_ERR("NO MEMORY : noti == NULL"); return NULL; } - ret = notification_noti_get_by_priv_id(noti, pkgname, priv_id); + ret = notification_ipc_request_load_noti_by_priv_id(noti, pkgname, priv_id); if (ret != NOTIFICATION_ERROR_NONE) { notification_free(noti); return NULL; diff --git a/src/notification_ipc.c b/src/notification_ipc.c index b74ab04..d04d647 100755 --- a/src/notification_ipc.c +++ b/src/notification_ipc.c @@ -23,50 +23,92 @@ #include <string.h> #include <stdlib.h> #include <errno.h> - #include <vconf.h> - -#include <packet.h> -#include <com-core.h> -#include <com-core_packet.h> +#include <bundle_internal.h> #include <notification_ipc.h> #include <notification_db.h> #include <notification_type.h> #include <notification_private.h> #include <notification_debug.h> +#include <notification_setting.h> #include <notification_setting_internal.h> - -#define NOTIFICATION_IPC_TIMEOUT 0.0 - -#if !defined(VCONFKEY_MASTER_STARTED) -#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" -#endif - -static struct info { - int server_fd; - int server_cl_fd; - int server_cl_fd_ref_cnt; - int client_fd; - const char *socket_file; - struct { - int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data); - void *data; - } server_cb; - int initialized; - int is_started_cb_set_svc; - int is_started_cb_set_task; -} s_info = { - .server_fd = -1, - .server_cl_fd = -1, - .server_cl_fd_ref_cnt = 0, - .client_fd = -1, - .socket_file = NOTIFICATION_ADDR, - .initialized = 0, - .is_started_cb_set_svc = 0, - .is_started_cb_set_task = 0, +#include <notification_internal.h> + +#include <gio/gio.h> + +#define PROVIDER_BUS_NAME "org.tizen.data_provider_service" +#define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service" +#define PROVIDER_NOTI_INTERFACE_NAME "org.tizen.data_provider_noti_service" + +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" + +static const gchar *_bus_name = NULL; +static GDBusConnection *_gdbus_conn = NULL; +static int monitor_id = 0; +static int provider_monitor_id = 0; +static int is_master_started = 0; + +static const char *NOTI_DATA_STRING[] = { + "NOTIFICATION_DATA_TYPE_NOTI_TYPE", + "NOTIFICATION_DATA_TYPE_LAYOUT", + "NOTIFICATION_DATA_TYPE_GROUP_ID", + "NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID", + "NOTIFICATION_DATA_TYPE_PRIV_ID", + "NOTIFICATION_DATA_TYPE_CALLER_PKGNAME", + "NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME", + "NOTIFICATION_DATA_TYPE_ARGS", + "NOTIFICATION_DATA_TYPE_GROUP_ARGS", + "NOTIFICATION_DATA_TYPE_EXECUTE_OPTION", + "NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING", + "NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH", + "NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH", + "NOTIFICATION_DATA_TYPE_BUTTON1_EVENT", + "NOTIFICATION_DATA_TYPE_BUTTON2_EVENT", + "NOTIFICATION_DATA_TYPE_BUTTON3_EVENT", + "NOTIFICATION_DATA_TYPE_BUTTON4_EVENT", + "NOTIFICATION_DATA_TYPE_BUTTON5_EVENT", + "NOTIFICATION_DATA_TYPE_BUTTON6_EVENT", + "NOTIFICATION_DATA_TYPE_ICON_EVENT", + "NOTIFICATION_DATA_TYPE_THUMBNAIL_EVENT", + "NOTIFICATION_DATA_TYPE_DOMAIN", + "NOTIFICATION_DATA_TYPE_DIR", + "NOTIFICATION_DATA_TYPE_TEXT", + "NOTIFICATION_DATA_TYPE_KEY", + "NOTIFICATION_DATA_TYPE_FORMAT_ARGS", + "NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS", + "NOTIFICATION_DATA_TYPE_IMAGE_PATH", + "NOTIFICATION_DATA_TYPE_SOUND_TYPE", + "NOTIFICATION_DATA_TYPE_SOUND_PATH", + "NOTIFICATION_DATA_TYPE_VIBRATION_TYPE", + "NOTIFICATION_DATA_TYPE_VIBRATION_PATH", + "NOTIFICATION_DATA_TYPE_LED_OPERATION", + "NOTIFICATION_DATA_TYPE_LED_ARGB", + "NOTIFICATION_DATA_TYPE_LED_ON_MS", + "NOTIFICATION_DATA_TYPE_LED_OFF_MS", + "NOTIFICATION_DATA_TYPE_TIME", + "NOTIFICATION_DATA_TYPE_INSERT_TIME", + "NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY", + "NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST", + "NOTIFICATION_DATA_TYPE_PROGRESS_SIZE", + "NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE", + "NOTIFICATION_DATA_TYPE_APP_ICON_PATH", + "NOTIFICATION_DATA_TYPE_APP_NAME", + "NOTIFICATION_DATA_TYPE_TEMP_TITLE", + "NOTIFICATION_DATA_TYPE_TEMP_CONTENT", + "NOTIFICATION_DATA_TYPE_TAG", + "NOTIFICATION_DATA_TYPE_ONGOING_FLAG", + "NOTIFICATION_DATA_TYPE_AUTO_REMOVE", }; + +typedef struct _result_cb_item { + void (*result_cb)(int priv_id, int result, void *data); + void *data; +} result_cb_item; + typedef struct _task_list task_list; struct _task_list { task_list *prev; @@ -76,17 +118,30 @@ struct _task_list { void *data; }; -typedef struct _result_cb_item { - void (*result_cb)(int priv_id, int result, void *data); - void *data; -} result_cb_item; - static task_list *g_task_list; -static int notification_ipc_monitor_register(void); -static int notification_ipc_monitor_deregister(void); +static int _ipc_monitor_register(void); +static int _ipc_monitor_deregister(void); static void _do_deffered_task(void); -static void _master_started_cb_task(keynode_t *node, void *data); + +static void _print_noti(notification_h noti) { + char *pkgname = NULL; + char *text = NULL; + char *content = NULL; + const char *tag = NULL; + + notification_get_pkgname(noti, &pkgname); + notification_get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, &text); + notification_get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, &content); + notification_get_tag(noti, &tag); + + NOTIFICATION_DBG("client print_noti pkgname = %s ", pkgname ); + NOTIFICATION_DBG("client print_noti title = %s ", text ); + NOTIFICATION_DBG("client print_noti content = %s ", content ); + NOTIFICATION_DBG("client print_noti tag = %s ", tag ); + NOTIFICATION_DBG("client print_noti priv_id = %d ", noti->priv_id); + NOTIFICATION_DBG("client print_noti vibration_path = %s ", noti->vibration_path); +} static inline char *_string_get(char *string) { @@ -99,50 +154,61 @@ static inline char *_string_get(char *string) return string; } -/*! - * functions to check state of master - */ -static inline void _set_master_started_cb(vconf_callback_fn cb) -{ - int ret = -1; - - ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, cb, NULL); - if (ret != 0) - NOTIFICATION_ERR("failed to notify key(%s) : %d", - VCONFKEY_MASTER_STARTED, ret); -} - -static inline void _unset_master_started_cb(vconf_callback_fn cb) -{ - int ret = -1; - - ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, cb); - if (ret != 0) - NOTIFICATION_ERR("failed to notify key(%s) : %d", - VCONFKEY_MASTER_STARTED, ret); -} int notification_ipc_is_master_ready(void) { - int ret = -1, is_master_started = 0; - - ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started); - if (ret == 0 && is_master_started == 1) { - NOTIFICATION_ERR("the master has been started"); - } else { + GVariant *result; + GError *err = NULL; + gboolean name_exist; + + result = g_dbus_connection_call_sync( + _gdbus_conn, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "NameHasOwner", + g_variant_new("(s)", PROVIDER_BUS_NAME), + G_VARIANT_TYPE("(b)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if (err || (result == NULL)) { + if (err) { + NOTIFICATION_ERR("No reply. error = %s", err->message); + g_error_free(err); + } is_master_started = 0; - NOTIFICATION_ERR("the master has been stopped"); + } else { + g_variant_get(result, "(b)", &name_exist); + + if (!name_exist) { + NOTIFICATION_ERR("Name not exist %s", PROVIDER_BUS_NAME); + NOTIFICATION_ERR("the master has been stopped"); + is_master_started = 0; + } else { + NOTIFICATION_DBG("the master has been started"); + is_master_started = 1; + } } + if(result) + g_variant_unref(result); + return is_master_started; } +/* TODO: dbus activation isn't enough ? */ +/* + * store tasks when daemon stopped + */ int notification_ipc_add_deffered_task( void (*deferred_task_cb)(void *data), void *user_data) { - task_list *list = NULL; - task_list *list_new = NULL; + task_list *list; + task_list *list_new; list_new = (task_list *) malloc(sizeof(task_list)); @@ -150,11 +216,6 @@ int notification_ipc_add_deffered_task( if (list_new == NULL) return NOTIFICATION_ERROR_OUT_OF_MEMORY; - if (s_info.is_started_cb_set_task == 0) { - _set_master_started_cb(_master_started_cb_task); - s_info.is_started_cb_set_task = 1; - } - list_new->next = NULL; list_new->prev = NULL; @@ -169,31 +230,27 @@ int notification_ipc_add_deffered_task( while (list->next != NULL) list = list->next; - list->next = list_new; list_new->prev = list; } return NOTIFICATION_ERROR_NONE; } -int -notification_ipc_del_deffered_task( +int notification_ipc_del_deffered_task( void (*deferred_task_cb)(void *data)) { - task_list *list_del = NULL; - task_list *list_prev = NULL; - task_list *list_next = NULL; + task_list *list_del; + task_list *list_prev; + task_list *list_next; list_del = g_task_list; if (list_del == NULL) return NOTIFICATION_ERROR_INVALID_PARAMETER; - while (list_del->prev != NULL) list_del = list_del->prev; - do { if (list_del->task_cb == deferred_task_cb) { list_prev = list_del->prev; @@ -207,20 +264,11 @@ notification_ipc_del_deffered_task( if (list_next == NULL) { if (list_prev != NULL) list_prev->next = NULL; - } else { list_next->prev = list_prev; } free(list_del); - - if (g_task_list == NULL) { - if (s_info.is_started_cb_set_task == 1) { - _unset_master_started_cb(_master_started_cb_task); - s_info.is_started_cb_set_task = 0; - } - } - return NOTIFICATION_ERROR_NONE; } list_del = list_del->next; @@ -231,23 +279,18 @@ notification_ipc_del_deffered_task( static void _do_deffered_task(void) { - task_list *list_do = NULL; - task_list *list_temp = NULL; + task_list *list_do; + task_list *list_temp; if (g_task_list == NULL) return; list_do = g_task_list; g_task_list = NULL; - if (s_info.is_started_cb_set_task == 1) { - _unset_master_started_cb(_master_started_cb_task); - s_info.is_started_cb_set_task = 0; - } while (list_do->prev != NULL) list_do = list_do->prev; - while (list_do != NULL) { if (list_do->task_cb != NULL) { list_do->task_cb(list_do->data); @@ -259,43 +302,14 @@ static void _do_deffered_task(void) } } -static void _master_started_cb_service(keynode_t *node, - void *data) { - int ret = NOTIFICATION_ERROR_NONE; - - if (notification_ipc_is_master_ready()) { - NOTIFICATION_ERR("try to register a notification service"); - ret = notification_ipc_monitor_deregister(); - if (ret != NOTIFICATION_ERROR_NONE) - NOTIFICATION_ERR("failed to unregister a monitor"); - - ret = notification_ipc_monitor_register(); - if (ret != NOTIFICATION_ERROR_NONE) - NOTIFICATION_ERR("failed to register a monitor"); - - } else { - NOTIFICATION_ERR("try to unregister a notification service"); - ret = notification_ipc_monitor_deregister(); - if (ret != NOTIFICATION_ERROR_NONE) - NOTIFICATION_ERR("failed to deregister a monitor"); - - } -} - -static void _master_started_cb_task(keynode_t *node, - void *data) { - - if (notification_ipc_is_master_ready()) - _do_deffered_task(); -} - /*! * functions to create operation list */ -notification_op *notification_ipc_create_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list) +static notification_op *_ipc_create_op(notification_op_type_e type, + int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list) { - int i = 0; - notification_op *op_list = NULL; + int i; + notification_op *op_list; if (num_op <= 0) return NULL; @@ -313,7 +327,6 @@ notification_op *notification_ipc_create_op(notification_op_type_e type, int num (op_list + i)->type = type; if (list_priv_id != NULL) (op_list + i)->priv_id = *(list_priv_id + i); - if (noti_list != NULL) (op_list + i)->noti = *(noti_list + i); } @@ -330,7 +343,6 @@ static inline char *_dup_string(const char *string) if (string == NULL) return NULL; - if (string[0] == '\0') return NULL; @@ -341,1261 +353,1520 @@ static inline char *_dup_string(const char *string) return ret; } -static inline bundle *_create_bundle_from_string(unsigned char *string) +static inline bundle *_create_bundle_from_bundle_raw(bundle_raw *string) { if (string == NULL) return NULL; - if (string[0] == '\0') return NULL; return bundle_decode(string, strlen((char *)string)); } -/*! - * functions creating notification packet - */ -EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet) +static void _add_noti_notify(GVariant *parameters) { - int i = 0; - int ret = 0; - int type; - int layout; - int group_id; - int internal_group_id; - int priv_id; - char *caller_pkgname = NULL; - char *launch_pkgname = NULL; - unsigned char *args = NULL; - unsigned char *group_args = NULL; - unsigned char *b_execute_option = NULL; - unsigned char *b_service_responding = NULL; - unsigned char *b_service_single_launch = NULL; - unsigned char *b_service_multi_launch = NULL; - unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, }; - char *domain = NULL; - char *dir = NULL; - unsigned char *b_text = NULL; - unsigned char *b_key = NULL; - unsigned char *b_format_args = NULL; - int num_format_args; - unsigned char *b_image_path = NULL; - int sound_type; - char *sound_path = NULL; - int vibration_type; - char *vibration_path = NULL; - int led_operation; - int led_argb; - int led_on_ms; - int led_off_ms; - time_t time; - time_t insert_time; - int flags_for_property; - int display_applist; - double progress_size; - double progress_percentage; - char *app_icon_path = NULL; - char *app_name = NULL; - char *temp_title = NULL; - char *temp_content = NULL; - char *tag = NULL; - bool *ongoing_flag; - bool *auto_remove; + notification_h noti; + notification_op *noti_op; + GVariant *body = NULL; - if (noti == NULL) { - NOTIFICATION_ERR("invalid data"); - return NOTIFICATION_ERROR_INVALID_PARAMETER; + NOTIFICATION_DBG("add noti notify"); + noti = notification_create(NOTIFICATION_TYPE_NOTI); + if (!noti) { + NOTIFICATION_ERR("failed to create a notification"); + return; } - ret = packet_get(packet, - "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii", - &type, - &layout, - &group_id, - &internal_group_id, - &priv_id, - &caller_pkgname, - &launch_pkgname, - &args, - &group_args, - &b_execute_option, - &b_service_responding, - &b_service_single_launch, - &b_service_multi_launch, - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON], - &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL], - &domain, - &dir, - &b_text, - &b_key, - &b_format_args, - &num_format_args, - &b_image_path, - &sound_type, - &sound_path, - &vibration_type, - &vibration_path, - &led_operation, - &led_argb, - &led_on_ms, - &led_off_ms, - &time, - &insert_time, - &flags_for_property, - &display_applist, - &progress_size, - &progress_percentage, - &app_icon_path, - &app_name, - &temp_title, - &temp_content, - &tag, - &ongoing_flag, - &auto_remove); - - if (ret != 49) { - NOTIFICATION_ERR("failed to create a noti from packet"); - return NOTIFICATION_ERROR_INVALID_PARAMETER; - } + g_variant_get(parameters, "(v)", &body); + notification_ipc_make_noti_from_gvariant(noti, body); + _print_noti(noti); + if (noti->flags_for_property & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) { + NOTIFICATION_ERR("disable changed callback %d", noti->flags_for_property); + /* Disable changed cb */ + } else { + /* Enable changed cb */ + noti_op = _ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i); - /*! - * This is already allocated from the notification_create function. - * Before reallocate string to here. - * We have to release old one first. - */ - free(noti->caller_pkgname); - noti->caller_pkgname = _dup_string(caller_pkgname); - noti->launch_pkgname = _dup_string(launch_pkgname); - noti->args = _create_bundle_from_string(args); - noti->group_args = _create_bundle_from_string(group_args); - noti->b_execute_option = _create_bundle_from_string(b_execute_option); - noti->b_service_responding = _create_bundle_from_string(b_service_responding); - noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch); - noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch); - for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) - noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]); + if (noti_op != NULL) { + notification_call_changed_cb(noti_op, 1); + free(noti_op); + } + } + notification_free(noti); +} - noti->domain = _dup_string(domain); - noti->dir = _dup_string(dir); - noti->b_text = _create_bundle_from_string(b_text); - noti->b_key = _create_bundle_from_string(b_key); - noti->b_format_args = _create_bundle_from_string(b_format_args); - noti->b_image_path = _create_bundle_from_string(b_image_path); - noti->sound_path = _dup_string(sound_path); - noti->vibration_path = _dup_string(vibration_path); - noti->app_icon_path = _dup_string(app_icon_path); - noti->app_name = _dup_string(app_name); - noti->temp_title = _dup_string(temp_title); - noti->temp_content = _dup_string(temp_content); +static void _update_noti_notify(GVariant *parameters) +{ + notification_h noti; + notification_op *noti_op; + GVariant *body = NULL; - noti->type = type; - noti->layout = layout; - noti->group_id = group_id; - noti->internal_group_id = internal_group_id; - noti->priv_id = priv_id; - noti->num_format_args = num_format_args; - noti->sound_type = sound_type; - noti->vibration_type = vibration_type; - noti->led_operation = led_operation; - noti->led_argb = led_argb; - noti->led_on_ms = led_on_ms; - noti->led_off_ms = led_off_ms; - noti->time = time; - noti->insert_time = insert_time; - noti->flags_for_property = flags_for_property; - noti->display_applist = display_applist; - noti->progress_size = progress_size; - noti->progress_percentage = progress_percentage; - noti->tag = _dup_string(tag); - noti->ongoing_flag = ongoing_flag; - noti->auto_remove = auto_remove; + noti = notification_create(NOTIFICATION_TYPE_NOTI); + if (!noti) { + NOTIFICATION_ERR("failed to create a notification"); + return; + } + g_variant_get(parameters, "(v)", &body); + notification_ipc_make_noti_from_gvariant(noti, body); + _print_noti(noti); - return NOTIFICATION_ERROR_NONE; + noti_op = _ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i); + if (noti_op != NULL) { + notification_call_changed_cb(noti_op, 1); + free(noti_op); + } + notification_free(noti); } -EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type) +static void _refresh_noti_notify(GVariant *parameters) { - int i = 0; - int b_encode_len = 0; - struct packet *result = NULL; - char *args = NULL; - char *group_args = NULL; - char *b_image_path = NULL; - char *b_execute_option = NULL; - char *b_service_responding = NULL; - char *b_service_single_launch = NULL; - char *b_service_multi_launch = NULL; - char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , }; - char *b_text = NULL; - char *b_key = NULL; - char *b_format_args = NULL; - struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...); - char *title_key = NULL; - char buf_key[32] = { 0, }; - - /* Decode bundle to insert DB */ - if (noti->args) - bundle_encode(noti->args, (bundle_raw **) & args, NULL); - - if (noti->group_args) - bundle_encode(noti->group_args, (bundle_raw **) & group_args, - &b_encode_len); + notification_op *noti_op = _ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL); - if (noti->b_execute_option) - bundle_encode(noti->b_execute_option, - (bundle_raw **) & b_execute_option, &b_encode_len); + if (noti_op != NULL) { + notification_call_changed_cb(noti_op, 1); + free(noti_op); + } +} - if (noti->b_service_responding) - bundle_encode(noti->b_service_responding, - (bundle_raw **) & b_service_responding, &b_encode_len); +static void _delete_single_notify(GVariant *parameters) +{ + int num_deleted; + int priv_id; + notification_op *noti_op; - if (noti->b_service_single_launch) - bundle_encode(noti->b_service_single_launch, - (bundle_raw **) & b_service_single_launch, &b_encode_len); + /* num_deleted ?? */ + g_variant_get(parameters, "(ii)", &num_deleted, &priv_id); - if (noti->b_service_multi_launch) - bundle_encode(noti->b_service_multi_launch, - (bundle_raw **) & b_service_multi_launch, &b_encode_len); + noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL); + if (noti_op != NULL) { + notification_call_changed_cb(noti_op, 1); + free(noti_op); + } +} - for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { - if (noti->b_event_handler[i]) - bundle_encode(noti->b_event_handler[i], - (bundle_raw **) & b_event_handler[i], &b_encode_len); +static void _delete_multiple_notify(GVariant *parameters) +{ + int buf[100] = {0,}; + int idx = 0; + notification_op *noti_op; + GVariantIter *iter; + g_variant_get(parameters, "(a(i))", &iter); + while (g_variant_iter_loop(iter, "(i)", &buf[idx])) { + NOTIFICATION_DBG("delete_noti_multiple priv_id : %d", buf[idx]); + idx++; } + g_variant_iter_free(iter); - if (noti->b_text) - bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len); + NOTIFICATION_DBG("data num deleted:%d", idx); + noti_op = _ipc_create_op(NOTIFICATION_OP_DELETE, idx, buf, idx, NULL); - if (noti->b_key) - bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len); + if (noti_op == NULL) { + NOTIFICATION_ERR("_ipc_create_op failed"); + return; + } + notification_call_changed_cb(noti_op, idx); + free(noti_op); +} - if (noti->b_format_args) - bundle_encode(noti->b_format_args, - (bundle_raw **) & b_format_args, &b_encode_len); +static void _handle_noti_notify(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NOTIFICATION_DBG("signal_name: %s", signal_name); + + if (g_strcmp0(signal_name, "add_noti_notify") == 0) + _add_noti_notify(parameters); + else if (g_strcmp0(signal_name, "update_noti_notify") == 0) + _update_noti_notify(parameters); + else if (g_strcmp0(signal_name, "delete_single_notify") == 0) + _delete_single_notify(parameters); + else if (g_strcmp0(signal_name, "delete_multiple_notify") == 0) + _delete_multiple_notify(parameters); + else if (g_strcmp0(signal_name, "refresh_noti_notify") == 0) + _refresh_noti_notify(parameters); +} - if (noti->b_image_path) - bundle_encode(noti->b_image_path, - (bundle_raw **) & b_image_path, &b_encode_len); - - if (noti->b_key != NULL) { - snprintf(buf_key, sizeof(buf_key), "%d", - NOTIFICATION_TEXT_TYPE_TITLE); - - bundle_get_str(noti->b_key, buf_key, &title_key); - } - - if (title_key == NULL && noti->b_text != NULL) { - snprintf(buf_key, sizeof(buf_key), "%d", - NOTIFICATION_TEXT_TYPE_TITLE); - - bundle_get_str(noti->b_text, buf_key, &title_key); - } - - if (title_key == NULL) - title_key = noti->caller_pkgname; - - - if (packet_type == 1) - func_to_create_packet = packet_create; - else if (packet_type == 2) - func_to_create_packet = packet_create_noack; - else - goto out; - - result = func_to_create_packet(command, - "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii", - noti->type, - noti->layout, - noti->group_id, - noti->internal_group_id, - noti->priv_id, - NOTIFICATION_CHECK_STR(noti->caller_pkgname), - NOTIFICATION_CHECK_STR(noti->launch_pkgname), - NOTIFICATION_CHECK_STR(args), - NOTIFICATION_CHECK_STR(group_args), - NOTIFICATION_CHECK_STR(b_execute_option), - NOTIFICATION_CHECK_STR(b_service_responding), - NOTIFICATION_CHECK_STR(b_service_single_launch), - NOTIFICATION_CHECK_STR(b_service_multi_launch), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]), - NOTIFICATION_CHECK_STR(noti->domain), - NOTIFICATION_CHECK_STR(noti->dir), - NOTIFICATION_CHECK_STR(b_text), - NOTIFICATION_CHECK_STR(b_key), - NOTIFICATION_CHECK_STR(b_format_args), - noti->num_format_args, - NOTIFICATION_CHECK_STR(b_image_path), - noti->sound_type, - NOTIFICATION_CHECK_STR(noti->sound_path), - noti->vibration_type, - NOTIFICATION_CHECK_STR(noti->vibration_path), - noti->led_operation, - noti->led_argb, - noti->led_on_ms, - noti->led_off_ms, - noti->time, - noti->insert_time, - noti->flags_for_property, - noti->display_applist, - noti->progress_size, - noti->progress_percentage, - NOTIFICATION_CHECK_STR(noti->app_icon_path), - NOTIFICATION_CHECK_STR(noti->app_name), - NOTIFICATION_CHECK_STR(noti->temp_title), - NOTIFICATION_CHECK_STR(noti->temp_content), - NOTIFICATION_CHECK_STR(noti->tag), - noti->ongoing_flag, - noti->auto_remove); - -out: - /* Free decoded data */ - if (args) - free(args); - - if (group_args) - free(group_args); - - if (b_execute_option) - free(b_execute_option); - - if (b_service_responding) - free(b_service_responding); - - if (b_service_single_launch) - free(b_service_single_launch); - - if (b_service_multi_launch) - free(b_service_multi_launch); - for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { - if (b_event_handler[i]) - free(b_event_handler[i]); +static int _dbus_signal_init() +{ + int id; + int ret = NOTIFICATION_ERROR_NONE; + + if (monitor_id == 0) { + id = g_dbus_connection_signal_subscribe(_gdbus_conn, + PROVIDER_BUS_NAME, + PROVIDER_NOTI_INTERFACE_NAME, /* interface */ + NULL, /* member */ + PROVIDER_OBJECT_PATH, /* path */ + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + _handle_noti_notify, + NULL, + NULL); + + NOTIFICATION_DBG("subscribe id : %d", id); + if (id == 0) { + ret = NOTIFICATION_ERROR_IO_ERROR; + NOTIFICATION_ERR("Failed to _register_noti_dbus_interface"); + } else { + monitor_id = id; + ret = NOTIFICATION_ERROR_NONE; + } } + return ret; +} - if (b_text) - free(b_text); - if (b_key) - free(b_key); +static int _dbus_init() +{ + int ret = NOTIFICATION_ERROR_NONE; + GError *error = NULL; - if (b_format_args) - free(b_format_args); + if (_gdbus_conn == NULL) { + _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (b_image_path) - free(b_image_path); + if (_gdbus_conn == NULL) { + if (error != NULL) { + NOTIFICATION_ERR("Failed to get dbus [%s]", error->message); + g_error_free(error); + } + return NOTIFICATION_ERROR_IO_ERROR; + } + _bus_name = g_dbus_connection_get_unique_name(_gdbus_conn); + NOTIFICATION_DBG("bus name : %s", _bus_name); - return result; + notification_error_quark(); + + ret = NOTIFICATION_ERROR_NONE; + } + return ret; } -EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet) +static int _send_sync_noti(GVariant *body, GDBusMessage **reply, char *cmd) { - int i = 0; - int b_encode_len = 0; - struct packet *result = NULL; - char *args = NULL; - char *group_args = NULL; - char *b_image_path = NULL; - char *b_execute_option = NULL; - char *b_service_responding = NULL; - char *b_service_single_launch = NULL; - char *b_service_multi_launch = NULL; - char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , }; - char *b_text = NULL; - char *b_key = NULL; - char *b_format_args = NULL; - char *title_key = NULL; - char buf_key[32] = { 0, }; - - /* Decode bundle to insert DB */ - if (noti->args) - bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len); - - if (noti->group_args) - bundle_encode(noti->group_args, (bundle_raw **) & group_args, - &b_encode_len); + int ret = NOTIFICATION_ERROR_NONE; + GError *err = NULL; + GDBusMessage *msg; + + msg = g_dbus_message_new_method_call( + PROVIDER_BUS_NAME, + PROVIDER_OBJECT_PATH, + PROVIDER_NOTI_INTERFACE_NAME, + cmd); + if (!msg) { + NOTIFICATION_ERR("Can't allocate new method call"); + if (body) + g_variant_unref(body); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + } - if (noti->b_execute_option) - bundle_encode(noti->b_execute_option, - (bundle_raw **) & b_execute_option, &b_encode_len); + if (body != NULL) + g_dbus_message_set_body(msg, body); - if (noti->b_service_responding) - bundle_encode(noti->b_service_responding, - (bundle_raw **) & b_service_responding, &b_encode_len); + *reply = g_dbus_connection_send_message_with_reply_sync( + _gdbus_conn, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + &err); - if (noti->b_service_single_launch) - bundle_encode(noti->b_service_single_launch, - (bundle_raw **) & b_service_single_launch, &b_encode_len); + g_object_unref(msg); - if (noti->b_service_multi_launch) - bundle_encode(noti->b_service_multi_launch, - (bundle_raw **) & b_service_multi_launch, &b_encode_len); + if (!*reply) { + if (err != NULL) { + NOTIFICATION_ERR("No reply. cmd = %s, error = %s", cmd, err->message); + g_error_free(err); + } + return NOTIFICATION_ERROR_SERVICE_NOT_READY; + } - for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { - if (noti->b_event_handler[i]) - bundle_encode(noti->b_event_handler[i], - (bundle_raw **) & b_event_handler[i], &b_encode_len); + if (g_dbus_message_to_gerror(*reply, &err)) { + ret = err->code; + NOTIFICATION_ERR("_send_sync_noti cmd = %s, error %s", cmd, err->message); + g_error_free(err); + return ret; } + NOTIFICATION_DBG("_send_sync_noti done !!"); + return NOTIFICATION_ERROR_NONE; - if (noti->b_text) - bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len); +} - if (noti->b_key) - bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len); +static void _send_message_with_reply_async_cb(GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *body; + int result = NOTIFICATION_ERROR_NONE; + int priv_id; + GDBusMessage *reply = NULL; + GError *err = NULL; + result_cb_item *cb_item = (result_cb_item *)user_data; - if (noti->b_format_args) - bundle_encode(noti->b_format_args, - (bundle_raw **) & b_format_args, &b_encode_len); + if (cb_item == NULL) { + NOTIFICATION_ERR("Failed to get a callback item"); + return; + } - if (noti->b_image_path) - bundle_encode(noti->b_image_path, - (bundle_raw **) & b_image_path, &b_encode_len); - - if (noti->b_key != NULL) { - snprintf(buf_key, sizeof(buf_key), "%d", - NOTIFICATION_TEXT_TYPE_TITLE); - - bundle_get_str(noti->b_key, buf_key, &title_key); - } - - if (title_key == NULL && noti->b_text != NULL) { - snprintf(buf_key, sizeof(buf_key), "%d", - NOTIFICATION_TEXT_TYPE_TITLE); - - bundle_get_str(noti->b_text, buf_key, &title_key); - } - - if (title_key == NULL) - title_key = noti->caller_pkgname; - - result = packet_create_reply(packet, - "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii", - noti->type, - noti->layout, - noti->group_id, - noti->internal_group_id, - noti->priv_id, - NOTIFICATION_CHECK_STR(noti->caller_pkgname), - NOTIFICATION_CHECK_STR(noti->launch_pkgname), - NOTIFICATION_CHECK_STR(args), - NOTIFICATION_CHECK_STR(group_args), - NOTIFICATION_CHECK_STR(b_execute_option), - NOTIFICATION_CHECK_STR(b_service_responding), - NOTIFICATION_CHECK_STR(b_service_single_launch), - NOTIFICATION_CHECK_STR(b_service_multi_launch), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]), - NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]), - NOTIFICATION_CHECK_STR(noti->domain), - NOTIFICATION_CHECK_STR(noti->dir), - NOTIFICATION_CHECK_STR(b_text), - NOTIFICATION_CHECK_STR(b_key), - NOTIFICATION_CHECK_STR(b_format_args), - noti->num_format_args, - NOTIFICATION_CHECK_STR(b_image_path), - noti->sound_type, - NOTIFICATION_CHECK_STR(noti->sound_path), - noti->vibration_type, - NOTIFICATION_CHECK_STR(noti->vibration_path), - noti->led_operation, - noti->led_argb, - noti->led_on_ms, - noti->led_off_ms, - noti->time, - noti->insert_time, - noti->flags_for_property, - noti->display_applist, - noti->progress_size, - noti->progress_percentage, - NOTIFICATION_CHECK_STR(noti->app_icon_path), - NOTIFICATION_CHECK_STR(noti->app_name), - NOTIFICATION_CHECK_STR(noti->temp_title), - NOTIFICATION_CHECK_STR(noti->temp_content), - NOTIFICATION_CHECK_STR(noti->tag), - noti->ongoing_flag, - noti->auto_remove); - - /* Free decoded data */ - if (args) - free(args); - - if (group_args) - free(group_args); - - if (b_execute_option) - free(b_execute_option); - - if (b_service_responding) - free(b_service_responding); - - if (b_service_single_launch) - free(b_service_single_launch); - - if (b_service_multi_launch) - free(b_service_multi_launch); + reply = g_dbus_connection_send_message_with_reply_finish( + connection, + res, + &err); + if (!reply) { + if (err != NULL) { + NOTIFICATION_ERR("No reply. error = %s", err->message); + g_error_free(err); + } + result = NOTIFICATION_ERROR_SERVICE_NOT_READY; - for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { - if (b_event_handler[i]) - free(b_event_handler[i]); + } else if (g_dbus_message_to_gerror(reply, &err)) { + result = err->code; + g_error_free(err); + NOTIFICATION_ERR("_send_async_noti error %s", err->message); } - if (b_text) - free(b_text); + NOTIFICATION_DBG("_send_async_noti done !![%d]", result); - if (b_key) - free(b_key); + if (result == NOTIFICATION_ERROR_NONE) { + body = g_dbus_message_get_body(reply); + g_variant_get(body, "(i)", &priv_id); - if (b_format_args) - free(b_format_args); + if (cb_item->result_cb) + cb_item->result_cb(priv_id, result, cb_item->data); - if (b_image_path) - free(b_image_path); + } else { + if (cb_item->result_cb) + cb_item->result_cb(NOTIFICATION_PRIV_ID_NONE, result, cb_item->data); + } - return result; + if (reply) + g_object_unref(reply); + free(cb_item); } -/*! - * functions to handler services - */ -static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet) +static int _send_async_noti(GVariant *body, result_cb_item *cb_item, char *cmd) { - notification_h noti = NULL; - notification_op *noti_op; - - if (!packet) { - NOTIFICATION_ERR("a packet is null"); - return NULL; - } - noti = notification_create(NOTIFICATION_TYPE_NOTI); - if (!noti) { - NOTIFICATION_ERR("failed to create a notification"); - return NULL; + GDBusMessage *msg; + + msg = g_dbus_message_new_method_call( + PROVIDER_BUS_NAME, + PROVIDER_OBJECT_PATH, + PROVIDER_NOTI_INTERFACE_NAME, + cmd); + if (!msg) { + NOTIFICATION_ERR("Can't allocate new method call"); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - notification_ipc_make_noti_from_packet(noti, packet); - if (noti->flags_for_property - & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) { - /* Disable changed cb */ - } else { - /* Enable changed cb */ - noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, ¬i); - if (noti_op != NULL) { - notification_call_changed_cb(noti_op, 1); - free(noti_op); - } - } - notification_free(noti); + if (body != NULL) + g_dbus_message_set_body(msg, body); + + g_dbus_connection_send_message_with_reply( + _gdbus_conn, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + (GAsyncReadyCallback)_send_message_with_reply_async_cb, + cb_item); + + NOTIFICATION_DBG("_send_async_noti done !!"); - return NULL; + g_object_unref(msg); + return NOTIFICATION_ERROR_NONE; } -static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet) +int notification_ipc_request_insert(notification_h noti, int *priv_id) { - notification_h noti = NULL; - notification_op *noti_op; - - if (!packet) { - NOTIFICATION_ERR("a packet is null"); - return NULL; + int result; + int id; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - noti = notification_create(NOTIFICATION_TYPE_NOTI); - if (!noti) { - NOTIFICATION_ERR("failed to create a notification"); - return NULL; + /* Initialize private ID */ + noti->priv_id = NOTIFICATION_PRIV_ID_NONE; + noti->group_id = NOTIFICATION_GROUP_ID_NONE; + noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE; + + _print_noti(noti); + body = notification_ipc_make_gvariant_from_noti(noti); + if (body == NULL) { + NOTIFICATION_ERR("cannot make gvariant"); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - notification_ipc_make_noti_from_packet(noti, packet); + result = _send_sync_noti(body, &reply, "add_noti"); + NOTIFICATION_DBG("_send_sync_noti %d", result); - noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, ¬i); - if (noti_op != NULL) { - notification_call_changed_cb(noti_op, 1); - free(noti_op); + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(i)", &id); + + if (priv_id != NULL) + *priv_id = id; } - notification_free(noti); + if(reply) + g_object_unref(reply); - return NULL; + NOTIFICATION_DBG("notification_ipc_request_insert done [priv_id : %d, result: %d]", *priv_id, result); + return result; } -static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet) +int notification_ipc_request_update(notification_h noti) { - notification_op *noti_op; + int result; + int priv_id; - if (!packet) { - NOTIFICATION_ERR("a packet is null"); - return NULL; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL); - if (noti_op != NULL) { - notification_call_changed_cb(noti_op, 1); - free(noti_op); + body = notification_ipc_make_gvariant_from_noti(noti); + if (body == NULL) { + NOTIFICATION_ERR("cannot make gvariant"); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - return NULL; + result = _send_sync_noti(body, &reply, "update_noti"); + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(i)", &priv_id); + } + + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_update done [result: %d, priv_id :%d]", result, priv_id); + return result; } -static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet) +int notification_ipc_request_update_async(notification_h noti, + void (*result_cb)(int priv_id, int result, void *data), void *user_data) { - int num_deleted = 0; - int priv_id = NOTIFICATION_PRIV_ID_NONE; - notification_op *noti_op; + int result; + result_cb_item *cb_item; + GVariant *body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - if (!packet) { - NOTIFICATION_ERR("a packet is null"); - return NULL; + cb_item = calloc(1, sizeof(result_cb_item)); + if (cb_item == NULL) + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + + cb_item->result_cb = result_cb; + cb_item->data = user_data; + + body = notification_ipc_make_gvariant_from_noti(noti); + if (body == NULL) { + NOTIFICATION_ERR("cannot make gvariant"); + free(cb_item); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) { - noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL); - if (noti_op != NULL) { - notification_call_changed_cb(noti_op, 1); - free(noti_op); - } + + result = _send_async_noti(body, cb_item, "update_noti"); + NOTIFICATION_DBG("notification_ipc_request_update_async done [result: %d]", result); + + if (result != NOTIFICATION_ERROR_NONE) { + free(cb_item); + cb_item = NULL; } - return NULL; + g_variant_unref(body); + + return result; } -static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet) +int notification_ipc_request_refresh(void) { - int ret = 0; - int buf[10] = {0,}; - int num_deleted = 0; - notification_op *noti_op; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - NOTIFICATION_INFO("delete_noti_multiple"); + body = g_variant_new("(i)", NOTIFICATION_OP_REFRESH); + result = _send_sync_noti(body, &reply, "refresh_noti"); - if (!packet) { - NOTIFICATION_ERR("a packet is null"); - return NULL; - } - ret = packet_get(packet, "iiiiiiiiiii", &num_deleted, - &(buf[0]), - &(buf[1]), - &(buf[2]), - &(buf[3]), - &(buf[4]), - &(buf[5]), - &(buf[6]), - &(buf[7]), - &(buf[8]), - &(buf[9])); - - NOTIFICATION_INFO("packet data count:%d", ret); - NOTIFICATION_INFO("packet data num deleted:%d", num_deleted); + if(reply) + g_object_unref(reply); - int i = 0; - for (i = 0 ; i < 10 ; i++) - NOTIFICATION_INFO("packet data[%d]:%d", i, buf[i]); + NOTIFICATION_ERR("notification_ipc_request_refresh done [result: %d]", result); + return result; +} + +int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id) +{ + int result; + int id; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } + body = g_variant_new("(si)", pkgname, priv_id); + result = _send_sync_noti(body, &reply, "del_noti_single"); - if (ret == 11) { - noti_op = notification_ipc_create_op( - NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL); - if (noti_op == NULL) { - NOTIFICATION_ERR("notification_ipc_create_op failed"); - return NULL; - } - notification_call_changed_cb(noti_op, num_deleted); - free(noti_op); + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(i)", &id); } - return NULL; + if(reply) + g_object_unref(reply); + + NOTIFICATION_ERR("notification_ipc_request_delete_single done [result: %d]", result); + return result; } -static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data) +int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname) { - int ret; - notification_op *noti_op; + int result; + int num_deleted; + GVariant *body; + GVariant *reply_body; + GDBusMessage *reply = NULL; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - if (!packet) { - NOTIFICATION_ERR("Packet is not valid\n"); - ret = NOTIFICATION_ERROR_INVALID_PARAMETER; - } else if (packet_get(packet, "i", &ret) != 1) { - NOTIFICATION_ERR("Packet is not valid\n"); - ret = NOTIFICATION_ERROR_INVALID_PARAMETER; - } else { - if (ret == 0) { - noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL); - if (noti_op != NULL) { - notification_call_changed_cb(noti_op, 1); - free(noti_op); - } - } + body = g_variant_new("(si)", pkgname, type); + result = _send_sync_noti(body, &reply, "del_noti_multiple"); + + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(i)", &num_deleted); + NOTIFICATION_ERR("num deleted:%d", num_deleted); } - return ret; + + if(reply) + g_object_unref(reply); + + return result; } -/*! - * functions to initialize and register a monitor - */ -static int notification_ipc_monitor_register(void) +int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag) { - int ret; - struct packet *packet; - static struct method service_table[] = { - { - .cmd = "add_noti", - .handler = _handler_insert, - }, - { - .cmd = "update_noti", - .handler = _handler_update, - }, - { - .cmd = "refresh_noti", - .handler = _handler_refresh, - }, - { - .cmd = "del_noti_single", - .handler = _handler_delete_single, - }, - { - .cmd = "del_noti_multiple", - .handler = _handler_delete_multiple, - }, - { - .cmd = NULL, - .handler = NULL, - }, - }; - - if (s_info.initialized == 1) - return NOTIFICATION_ERROR_NONE; - else - s_info.initialized = 1; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + GVariant *noti_body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - NOTIFICATION_ERR("register a service\n"); + body = g_variant_new("(ss)", pkgname, tag); + result = _send_sync_noti(body, &reply, "load_noti_by_tag"); + + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(v)", ¬i_body); + + notification_ipc_make_noti_from_gvariant(noti, noti_body); + g_variant_unref(noti_body); + _print_noti(noti); - com_core_packet_use_thread(1); - s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table); - if (s_info.server_fd < 0) { - NOTIFICATION_ERR("Failed to make a connection to the master\n"); - return NOTIFICATION_ERROR_IO_ERROR; } - packet = packet_create("service_register", ""); - if (!packet) { - NOTIFICATION_ERR("Failed to build a packet\n"); - com_core_packet_client_fini(s_info.server_fd); - return NOTIFICATION_ERROR_IO_ERROR; + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_load_noti_by_tag done [result: %d]", result); + return result; +} + +int notification_ipc_request_load_noti_by_priv_id(notification_h noti, const char *pkgname, int priv_id) +{ + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + GVariant *noti_body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL); - NOTIFICATION_DBG("Service register sent: %d\n", ret); - packet_destroy(packet); - if (ret != 0) { - com_core_packet_client_fini(s_info.server_fd); - s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER; - ret = NOTIFICATION_ERROR_IO_ERROR; - } else { - ret = NOTIFICATION_ERROR_NONE; + body = g_variant_new("(si)", pkgname, priv_id); + result = _send_sync_noti(body, &reply, "load_noti_by_priv_id"); + + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(v)", ¬i_body); + + notification_ipc_make_noti_from_gvariant(noti, noti_body); + g_variant_unref(noti_body); + _print_noti(noti); } - NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd); - return ret; + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_load_noti_by_priv_id done [result: %d]", result); + return result; } -int notification_ipc_monitor_deregister(void) +int notification_ipc_request_get_count(notification_type_e type, + const char *pkgname, int group_id, int priv_id, int *count) { - if (s_info.initialized == 0) - return NOTIFICATION_ERROR_NONE; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + int re_count; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - com_core_packet_client_fini(s_info.server_fd); - s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER; + body = g_variant_new("(isii)", type, pkgname, group_id, priv_id); + result = _send_sync_noti(body, &reply, "get_noti_count"); - s_info.initialized = 0; + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(i)", &re_count); - return NOTIFICATION_ERROR_NONE; + *count = re_count; + NOTIFICATION_DBG("noti count [%d]", re_count); + } + + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_get_count done [result: %d]", result); + return result; } -int notification_ipc_monitor_init(void) +int notification_ipc_request_load_noti_grouping_list(notification_type_e type, int count, + notification_list_h *list) { - int ret = NOTIFICATION_ERROR_NONE; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + GVariant *iter_body; + GVariantIter *iter; + notification_h noti; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - if (notification_ipc_is_master_ready()) - ret = notification_ipc_monitor_register(); + body = g_variant_new("(ii)", type, count); + result = _send_sync_noti(body, &reply, "load_noti_grouping_list"); - if (s_info.is_started_cb_set_svc == 0) { - _set_master_started_cb(_master_started_cb_service); - s_info.is_started_cb_set_svc = 1; + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(a(v))", &iter); + + while (g_variant_iter_loop(iter, "(v)", &iter_body)) { + noti = notification_create(NOTIFICATION_TYPE_NOTI); + notification_ipc_make_noti_from_gvariant(noti, iter_body); + _print_noti(noti); + *list = notification_list_append(*list, noti); + } + g_variant_iter_free(iter); } - return ret; + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_load_noti_grouping_list done [result: %d]", result); + return result; } -int notification_ipc_monitor_fini(void) +int notification_ipc_request_load_noti_detail_list(const char *pkgname, + int group_id, + int priv_id, + int count, + notification_list_h *list) { - int ret = NOTIFICATION_ERROR_NONE; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + GVariant *iter_body; + GVariantIter *iter; + notification_h noti; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } + + body = g_variant_new("(siii)", pkgname, group_id, priv_id, count); + result = _send_sync_noti(body, &reply, "load_noti_detail_list"); - if (s_info.is_started_cb_set_svc == 1) { - _unset_master_started_cb(_master_started_cb_service); - s_info.is_started_cb_set_svc = 0; + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(a(v))", &iter); + + while (g_variant_iter_loop(iter, "(v)", &iter_body)) { + noti = notification_create(NOTIFICATION_TYPE_NOTI); + notification_ipc_make_noti_from_gvariant(noti, iter_body); + _print_noti(noti); + *list = notification_list_append(*list, noti); + } + g_variant_iter_free(iter); } - ret = notification_ipc_monitor_deregister(); + if(reply) + g_object_unref(reply); - return ret; + NOTIFICATION_DBG("notification_ipc_request_load_noti_detail_list done [result: %d]", result); + return result; } -/*! - * functions to request the service - */ -int notification_ipc_request_insert(notification_h noti, int *priv_id) +int notification_ipc_request_get_setting_array( + notification_setting_h *setting_array, + int *count) { - int status = 0; - int id = NOTIFICATION_PRIV_ID_NONE; - struct packet *packet; - struct packet *result; + int result; + GDBusMessage *reply = NULL; + GVariant *reply_body; + GVariant *iter_body; + GVariantIter *iter; + int setting_cnt; + notification_setting_h result_setting_array; + notification_setting_h temp; + int setting_idx; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - /* Initialize private ID */ - noti->priv_id = NOTIFICATION_PRIV_ID_NONE; - noti->group_id = NOTIFICATION_GROUP_ID_NONE; - noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE; + result = _send_sync_noti(NULL, &reply, "get_setting_array"); - packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(ia(v))", &setting_cnt, &iter); - if (result != NULL) { - if (packet_get(result, "ii", &status, &id) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; + NOTIFICATION_DBG("get setting arr cnt: %d", setting_cnt); + result_setting_array = (struct notification_setting *)malloc(sizeof(struct notification_setting) * setting_cnt); + if (result_setting_array == NULL) { + NOTIFICATION_ERR("malloc failed"); + g_object_unref(reply); + g_variant_iter_free(iter); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - if (status != NOTIFICATION_ERROR_NONE) { - packet_unref(result); - return status; + setting_idx = 0; + while (g_variant_iter_loop(iter, "(v)", &iter_body)) { + temp = result_setting_array + setting_idx; + notification_ipc_make_setting_from_gvariant(temp, iter_body); + setting_idx++; } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(insert)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + + *count = setting_cnt; + *setting_array = result_setting_array; + g_variant_iter_free(iter); } - if (priv_id != NULL) - *priv_id = id; + if(reply) + g_object_unref(reply); - return NOTIFICATION_ERROR_NONE; + NOTIFICATION_DBG("notification_ipc_request_get_setting_array done [result: %d]", result); + return result; } -int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id) +int notification_ipc_request_get_setting_by_package_name( + const char *package_name, notification_setting_h *setting) { - int status = 0; - int id = NOTIFICATION_PRIV_ID_NONE; - struct packet *packet; - struct packet *result; - - packet = packet_create("del_noti_single", "si", pkgname, priv_id); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &id) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body; + GVariant *setting_body; + notification_setting_h result_setting; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } + + body = g_variant_new("(s)", package_name); + result = _send_sync_noti(body, &reply, "get_setting_by_package_name"); + + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(reply_body, "(v)", &setting_body); + + result_setting = (struct notification_setting *)malloc(sizeof(struct notification_setting)); + if (result_setting == NULL) { + NOTIFICATION_ERR("malloc failed"); + g_object_unref(reply); + g_variant_unref(body); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(delete)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + notification_ipc_make_setting_from_gvariant(result_setting, setting_body); + + *setting = result_setting; + g_variant_unref(setting_body); } - return status; + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_get_setting_by_package_name done [result: %d]", result); + return result; } -int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname) +int notification_ipc_request_load_system_setting(notification_system_setting_h *setting) { - int status = 0; - int num_deleted = 0; - struct packet *packet; - struct packet *result; - - packet = packet_create("del_noti_multiple", "si", pkgname, type); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &num_deleted) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; + int result; + GDBusMessage *reply = NULL; + GVariant *setting_body; + GVariant *reply_body; + notification_system_setting_h result_setting; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } + + result = _send_sync_noti(NULL, &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); + + result_setting = (struct notification_system_setting *)malloc(sizeof(struct notification_system_setting)); + if (result_setting == NULL) { + NOTIFICATION_ERR("malloc failed"); + g_object_unref(reply); + return NOTIFICATION_ERROR_OUT_OF_MEMORY; } - NOTIFICATION_ERR("num deleted:%d", num_deleted); - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(delete multiple)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + notification_ipc_make_system_setting_from_gvariant(result_setting, setting_body); + + *setting = result_setting; + g_variant_unref(setting_body); } - return status; + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_request_load_system_setting done [result: %d]", result); + return result; } -int notification_ipc_request_update(notification_h noti) +int notification_ipc_update_setting(notification_setting_h setting) { - int status = 0; - int id = NOTIFICATION_PRIV_ID_NONE; - struct packet *packet; - struct packet *result; - - packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &id) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; - } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(update)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - return status; + body = g_variant_new("(siii)", + setting->package_name, + (int)(setting->allow_to_notify), + (int)(setting->do_not_disturb_except), + (int)(setting->visibility_class)); + + result = _send_sync_noti(body, &reply, "update_noti_setting"); + + if(reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_update_setting done [result: %d]", result); + return result; } -static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data) +int notification_ipc_update_system_setting(notification_system_setting_h system_setting) { - int status = 0; - int id = NOTIFICATION_PRIV_ID_NONE; - result_cb_item *cb_item = (result_cb_item *)data; + int result; + GDBusMessage *reply = NULL; + GVariant *body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; + } - if (cb_item == NULL) { - NOTIFICATION_ERR("Failed to get a callback item"); - return NOTIFICATION_ERROR_INVALID_PARAMETER; + body = g_variant_new("(ii)", + (int)(system_setting->do_not_disturb), + (int)(system_setting->visibility_class)); + + result = _send_sync_noti(body, &reply, "update_noti_sys_setting"); + + if (reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_update_system_setting done [result: %d]", result); + return result; +} + +int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value) +{ + int result; + GDBusMessage *reply = NULL; + GVariant *body; + + result = _dbus_init(); + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1; - if (s_info.server_cl_fd_ref_cnt <= 0) { - NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd); - int fd_temp = s_info.server_cl_fd; - s_info.server_cl_fd = -1; - com_core_packet_client_fini(fd_temp); - NOTIFICATION_DBG("FD(%d) finalized", fd_temp); + body = g_variant_new("(sss)", pkgname, property, value); + + result = _send_sync_noti(body, &reply, "set_noti_property"); + + if (reply) + g_object_unref(reply); + + NOTIFICATION_DBG("notification_ipc_noti_setting_property_set done [result: %d]", result); + return result; +} + +int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value) +{ + int result; + GDBusMessage *reply = NULL; + GVariant *body; + GVariant *reply_body = NULL; + gchar *ret_val; + + result = _dbus_init(); + + if (result != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", result); + return result; } - if (packet != NULL) { - if (packet_get(packet, "ii", &status, &id) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - status = NOTIFICATION_ERROR_IO_ERROR; + body = g_variant_new("(ss)", pkgname, property); + result = _send_sync_noti(body, &reply, "get_noti_property"); + + if (result == NOTIFICATION_ERROR_NONE) { + reply_body = g_dbus_message_get_body(reply); + g_variant_get(body, "(s)", &ret_val); + + if (ret_val != NULL) { + *value = g_strdup(ret_val); + g_free(ret_val); } } - if (cb_item->result_cb != NULL) - cb_item->result_cb(id, status, cb_item->data); + if(reply) + g_object_unref(reply); - free(cb_item); - - return status; + NOTIFICATION_DBG("notification_ipc_noti_setting_property_get done [result: %d]", result); + return result; } -int notification_ipc_request_update_async(notification_h noti, - void (*result_cb)(int priv_id, int result, void *data), void *user_data) +EXPORT_API GVariant *notification_ipc_make_gvariant_from_noti(notification_h noti) { - int ret = NOTIFICATION_ERROR_NONE; - int ret_con = 0; - struct packet *packet = NULL; - result_cb_item *cb_item = NULL; + NOTIFICATION_DBG("make gvariant from noti"); + int i = 0; + int b_encode_len = 0; + bundle_raw *args = NULL; + bundle_raw *group_args = NULL; + bundle_raw *b_image_path = NULL; + bundle_raw *b_execute_option = NULL; + bundle_raw *b_service_responding = NULL; + bundle_raw *b_service_single_launch = NULL; + bundle_raw *b_service_multi_launch = NULL; + bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = {NULL, }; + bundle_raw *b_text = NULL; + bundle_raw *b_key = NULL; + bundle_raw *b_format_args = NULL; + GVariant *body = NULL; + GVariant *result_body = NULL; + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{iv}")); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NOTI_TYPE, g_variant_new_int32(noti->type)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAYOUT, g_variant_new_int32(noti->layout)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ID, g_variant_new_int32(noti->group_id)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, g_variant_new_int32(noti->internal_group_id)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PRIV_ID, g_variant_new_int32(noti->priv_id)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, g_variant_new_string((const gchar *)noti->caller_pkgname)); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, g_variant_new_int32(noti->display_applist)); + + if (noti->args) { + bundle_encode(noti->args, (bundle_raw **)&args, NULL); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ARGS, g_variant_new_string((const gchar *)args)); + + if (args) + bundle_free_encoded_rawdata(&args); + } - packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1); - if (packet == NULL) { - ret = NOTIFICATION_ERROR_INVALID_PARAMETER; - goto fail; + if (noti->group_args) { + bundle_encode(noti->group_args, (bundle_raw **)&group_args, + &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_GROUP_ARGS, g_variant_new_string((const gchar *)group_args)); + + if (group_args) + bundle_free_encoded_rawdata(&group_args); } - cb_item = calloc(1, sizeof(result_cb_item)); - if (cb_item == NULL) { - ret = NOTIFICATION_ERROR_OUT_OF_MEMORY; - goto fail; + if (noti->b_execute_option) { + bundle_encode(noti->b_execute_option, + (bundle_raw **)&b_execute_option, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, g_variant_new_string((const gchar *)b_execute_option)); + + if (b_execute_option) + bundle_free_encoded_rawdata(&b_execute_option); } - if (s_info.server_cl_fd < 0) { - com_core_packet_use_thread(1); - s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL); - if (s_info.server_cl_fd < 0) { - NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd); - if (notification_ipc_is_master_ready() == 1) - ret = NOTIFICATION_ERROR_PERMISSION_DENIED; - else - ret = NOTIFICATION_ERROR_SERVICE_NOT_READY; + if (noti->b_service_responding) { + bundle_encode(noti->b_service_responding, + (bundle_raw **)&b_service_responding, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, g_variant_new_string((const gchar *)b_service_responding)); - goto fail; - } - s_info.server_cl_fd_ref_cnt = 1; - } else { - s_info.server_cl_fd_ref_cnt++; + if (b_service_responding) + bundle_free_encoded_rawdata(&b_service_responding); } - cb_item->result_cb = result_cb; - cb_item->data = user_data; + if (noti->b_service_single_launch) { + bundle_encode(noti->b_service_single_launch, + (bundle_raw **)&b_service_single_launch, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, g_variant_new_string((const gchar *)b_service_single_launch)); + + if (b_service_single_launch) + bundle_free_encoded_rawdata(&b_service_single_launch); + } + + if (noti->b_service_multi_launch) { + bundle_encode(noti->b_service_multi_launch, + (bundle_raw **)&b_service_multi_launch, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, g_variant_new_string((const gchar *)b_service_multi_launch)); + + if (b_service_multi_launch) + bundle_free_encoded_rawdata(&b_service_multi_launch); + } - NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd); - - ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f, - _notification_ipc_update_cb, cb_item); - if (ret_con < 0) { - NOTIFICATION_ERR("Failed to request update, %d\n", ret_con); - s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1; - if (s_info.server_cl_fd_ref_cnt <= 0) { - int fd_temp = s_info.server_cl_fd; - s_info.server_cl_fd = -1; - com_core_packet_client_fini(fd_temp); - NOTIFICATION_INFO("FD(%d) finalized", fd_temp); + for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { + if (noti->b_event_handler[i]) { + bundle_encode(noti->b_event_handler[i], + (bundle_raw **)&b_event_handler[i], &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_BUTTON1_EVENT + i, g_variant_new_string((const gchar *)b_event_handler[i])); + + if (b_event_handler[i]) + bundle_free_encoded_rawdata(&b_event_handler[i]); } - ret = NOTIFICATION_ERROR_IO_ERROR; - goto fail; - } else { - ret = NOTIFICATION_ERROR_NONE; - goto success; } -fail: - if (cb_item) free(cb_item); - NOTIFICATION_ERR("Err: %d\n", ret); + if (noti->launch_pkgname) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, g_variant_new_string((const gchar *)noti->launch_pkgname)); -success: - if (packet) packet_destroy(packet); + if (noti->domain != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DOMAIN, g_variant_new_string((const gchar *)noti->domain)); - return ret; + if (noti->dir != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_DIR, g_variant_new_string((const gchar *)noti->dir)); + + if (noti->b_text) { + bundle_encode(noti->b_text, (bundle_raw **)&b_text, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEXT, g_variant_new_string((const gchar *)b_text)); + + if (b_text) + bundle_free_encoded_rawdata(&b_text); + } + + if (noti->b_key) { + bundle_encode(noti->b_key, (bundle_raw **)&b_key, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_KEY, g_variant_new_string((const gchar *)b_key)); + + if (b_key) + bundle_free_encoded_rawdata(&b_key); + } + + if (noti->b_format_args) { + bundle_encode(noti->b_format_args, + (bundle_raw **)&b_format_args, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FORMAT_ARGS, g_variant_new_string((const gchar *)b_format_args)); + + if (b_format_args) + bundle_free_encoded_rawdata(&b_format_args); + } + + if (noti->num_format_args != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, g_variant_new_int32(noti->num_format_args)); + + if (noti->b_image_path) { + bundle_encode(noti->b_image_path, + (bundle_raw **)&b_image_path, &b_encode_len); + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_IMAGE_PATH, g_variant_new_string((const gchar *)b_image_path)); + + if (b_image_path) + bundle_free_encoded_rawdata(&b_image_path); + } + + if (noti->sound_type != NOTIFICATION_SOUND_TYPE_NONE) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_TYPE, g_variant_new_int32(noti->sound_type)); + + if (noti->sound_path) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_SOUND_PATH, g_variant_new_string((const gchar *)noti->sound_path)); + + if (noti->vibration_type != NOTIFICATION_VIBRATION_TYPE_NONE) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, g_variant_new_int32(noti->vibration_type)); + + if (noti->vibration_path) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_VIBRATION_PATH, g_variant_new_string((const gchar *)noti->vibration_path)); + + if (noti->led_operation != NOTIFICATION_LED_OP_OFF) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OPERATION, g_variant_new_int32(noti->led_operation)); + + if (noti->led_argb != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ARGB, g_variant_new_int32(noti->led_argb)); + + if (noti->led_on_ms != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_ON_MS, g_variant_new_int32(noti->led_on_ms)); + + if (noti->led_off_ms != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_LED_OFF_MS, g_variant_new_int32(noti->led_off_ms)); + + if (noti->time != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TIME, g_variant_new_int32(noti->time)); + + if (noti->insert_time != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_INSERT_TIME, g_variant_new_int32(noti->insert_time)); + + if (noti->flags_for_property != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, g_variant_new_int32(noti->flags_for_property)); + + if (noti->progress_size != 0.0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, g_variant_new_double(noti->progress_size)); + + if (noti->progress_percentage != 0.0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, g_variant_new_double(noti->progress_percentage)); + + if (noti->app_icon_path != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_ICON_PATH, g_variant_new_string((const gchar *)noti->app_icon_path)); + if (noti->app_name != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_APP_NAME, g_variant_new_string((const gchar *)noti->app_name)); + if (noti->temp_title != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_TITLE, g_variant_new_string((const gchar *)noti->temp_title)); + if (noti->temp_content != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TEMP_CONTENT, g_variant_new_string((const gchar *)noti->temp_content)); + if (noti->tag != NULL) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_TAG, g_variant_new_string((const gchar *)noti->tag)); + + if (noti->ongoing_flag != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_ONGOING_FLAG, g_variant_new_int32(noti->ongoing_flag)); + if (noti->auto_remove != 0) + g_variant_builder_add(&builder, "{iv}", NOTIFICATION_DATA_TYPE_AUTO_REMOVE, g_variant_new_int32(noti->auto_remove)); + + result_body = g_variant_builder_end(&builder); + body = g_variant_new("(v)", result_body); + + return body; } -int notification_ipc_request_refresh(void) -{ - int status = 0; - struct packet *packet; - struct packet *result; - - packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "i", &status) != 1) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; +static gboolean _variant_to_int_dict(GHashTable **dict, GVariant *variant) { + + GVariantIter iter; + int key; + int *hash_key; + GVariant *value; + + *dict = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, (GDestroyNotify)g_variant_unref); + if (*dict == NULL) + return FALSE; + + g_variant_iter_init(&iter, variant); + while (g_variant_iter_next(&iter, "{iv}", &key, &value)) { + hash_key = (int *)calloc(sizeof(int), 1); + if (hash_key == NULL) { + g_hash_table_remove_all(*dict); + return FALSE; } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(refresh)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + *hash_key = key; + g_hash_table_insert(*dict, (gpointer)hash_key, value); } + return TRUE; +} + +static gboolean _variant_dict_lookup(GHashTable *dict, + int key, + const gchar *format_string, + ...) +{ + GVariant *value; + va_list ap; - return status; + value = g_hash_table_lookup(dict, (gpointer)&key); + + if (value == NULL || !g_variant_check_format_string(value, format_string, FALSE)) + return FALSE; + + va_start(ap, format_string); + g_variant_get_va(value, format_string, NULL, &ap); + va_end(ap); + + return TRUE; } +/*! + * functions creating notification packet + */ +EXPORT_API int notification_ipc_make_noti_from_gvariant(notification_h noti, + GVariant *variant) { + + NOTIFICATION_DBG("make noti from GVariant"); + GHashTable *dict; -int notification_ipc_update_setting(notification_setting_h setting) -{ - int status = 0; - int ret = 0; - struct packet *packet; - struct packet *result; - - packet = packet_create("update_noti_setting", "siii", setting->package_name, (int)(setting->allow_to_notify), (int)(setting->do_not_disturb_except), (int)(setting->visibility_class)); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &ret) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; - } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(delete)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + int i; + char *caller_pkgname = NULL; + char *launch_pkgname = NULL; + bundle_raw *args = NULL; + bundle_raw *group_args = NULL; + bundle_raw *b_execute_option = NULL; + bundle_raw *b_service_responding = NULL; + bundle_raw *b_service_single_launch = NULL; + bundle_raw *b_service_multi_launch = NULL; + bundle_raw *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, }; + char *domain = NULL; + char *dir = NULL; + bundle_raw *b_text = NULL; + bundle_raw *b_key = NULL; + bundle_raw *b_format_args = NULL; + bundle_raw *b_image_path = NULL; + char *sound_path = NULL; + char *vibration_path = NULL; + char *app_icon_path = NULL; + char *app_name = NULL; + char *temp_title = NULL; + char *temp_content = NULL; + char *tag = NULL; + + if (noti == NULL) { + NOTIFICATION_ERR("invalid data noti NULL"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; + } + + if (variant == NULL) { + NOTIFICATION_ERR("invalid data variant NULL"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } - return status; + if (!_variant_to_int_dict(&dict, variant)) + return NOTIFICATION_ERROR_OUT_OF_MEMORY; + + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NOTI_TYPE, "i", ¬i->type); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAYOUT, "i", ¬i->layout); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ID, "i", ¬i->group_id); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INTERNAL_GROUP_ID, "i", ¬i->internal_group_id); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PRIV_ID, "i", ¬i->priv_id); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_CALLER_PKGNAME, "&s", &caller_pkgname); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LAUNCH_PKGNAME, "&s", &launch_pkgname); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ARGS, "&s", &args); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_GROUP_ARGS, "&s", &group_args); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_EXECUTE_OPTION, "&s", &b_execute_option); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_RESPONDING, "&s", &b_service_responding); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_SINGLE_LAUNCH, "&s", &b_service_single_launch); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SERVICE_MULTI_LAUNCH, "&s", &b_service_multi_launch); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON1_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON2_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON3_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON4_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON5_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_BUTTON6_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ICON_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_THUMBNAIL_EVENT, "&s", ¬i->b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DOMAIN, "&s", &domain); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DIR, "&s", &dir); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEXT, "&s", &b_text); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_KEY, "&s", &b_key); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FORMAT_ARGS, "&s", &b_format_args); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_NUM_FORMAT_ARGS, "i", ¬i->num_format_args); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_IMAGE_PATH, "&s", &b_image_path); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_TYPE, "i", ¬i->sound_type); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_SOUND_PATH, "&s", &sound_path); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_TYPE, "i", ¬i->vibration_type); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_VIBRATION_PATH, "&s", &vibration_path); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OPERATION, "i", ¬i->led_operation); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ARGB, "i", ¬i->led_argb); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_ON_MS, "i", ¬i->led_on_ms); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_LED_OFF_MS, "i", ¬i->led_off_ms); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TIME, "i", ¬i->time); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_INSERT_TIME, "i", ¬i->insert_time); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_FLAGS_FOR_PROPERTY, "i", ¬i->flags_for_property); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_DISPLAY_APPLIST, "i", ¬i->display_applist); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_SIZE, "d", ¬i->progress_size); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_PROGRESS_PERCENTAGE, "d", ¬i->progress_percentage); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_ICON_PATH, "&s", &app_icon_path); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_APP_NAME, "&s", &app_name); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_TITLE, "&s", &temp_title); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TEMP_CONTENT, "&s", &temp_content); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_TAG, "&s", &tag); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_ONGOING_FLAG, "i", ¬i->ongoing_flag); + _variant_dict_lookup(dict, NOTIFICATION_DATA_TYPE_AUTO_REMOVE, "i", ¬i->auto_remove); + + noti->caller_pkgname = _dup_string(caller_pkgname); + noti->launch_pkgname = _dup_string(launch_pkgname); + noti->args = _create_bundle_from_bundle_raw(args); + noti->group_args = _create_bundle_from_bundle_raw(group_args); + noti->b_execute_option = _create_bundle_from_bundle_raw(b_execute_option); + noti->b_service_responding = _create_bundle_from_bundle_raw( + b_service_responding); + noti->b_service_single_launch = _create_bundle_from_bundle_raw( + b_service_single_launch); + noti->b_service_multi_launch = _create_bundle_from_bundle_raw( + b_service_multi_launch); + for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) { + noti->b_event_handler[i] = _create_bundle_from_bundle_raw( + b_event_handler[i]); + } + noti->domain = _dup_string(domain); + noti->dir = _dup_string(dir); + noti->b_text = _create_bundle_from_bundle_raw(b_text); + noti->b_key = _create_bundle_from_bundle_raw(b_key); + noti->b_format_args = _create_bundle_from_bundle_raw(b_format_args); + noti->b_image_path = _create_bundle_from_bundle_raw(b_image_path); + noti->sound_path = _dup_string(sound_path); + noti->vibration_path = _dup_string(vibration_path); + noti->app_icon_path = _dup_string(app_icon_path); + noti->app_name = _dup_string(app_name); + noti->temp_title = _dup_string(temp_title); + noti->temp_content = _dup_string(temp_content); + noti->tag = _dup_string(tag); + + g_hash_table_remove_all(dict); + + return NOTIFICATION_ERROR_NONE; } -int notification_ipc_update_system_setting(notification_system_setting_h system_setting) +EXPORT_API GVariant *notification_ipc_make_gvariant_from_system_setting(struct notification_system_setting *noti_setting) { - int status = 0; - int ret = 0; - struct packet *packet = NULL; - struct packet *result = NULL; - - packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class)); - if (packet == NULL) { - NOTIFICATION_ERR("packet_create failed."); - goto out; - } - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &ret) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - status = NOTIFICATION_ERROR_IO_ERROR; - goto out; - } + GVariant *body = NULL; + body = g_variant_new("(ii)", + noti_setting->do_not_disturb, + noti_setting->visibility_class); + return body; +} - } else { - NOTIFICATION_ERR("failed to receive answer(delete)"); - if (notification_ipc_is_master_ready() == 1) { - status = NOTIFICATION_ERROR_PERMISSION_DENIED; - goto out; - } else { - status = NOTIFICATION_ERROR_SERVICE_NOT_READY; - goto out; - } +EXPORT_API int notification_ipc_make_system_setting_from_gvariant(struct notification_system_setting *noti_setting, + GVariant *variant) +{ + int do_not_disturb; + int visibility_class; + + if (noti_setting == NULL) { + NOTIFICATION_ERR("invalid data"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } -out: - if (result) - packet_unref(result); + g_variant_get(variant, + "(ii)", + &do_not_disturb, + &visibility_class); + + NOTIFICATION_DBG("system setting #### %d, %d", + do_not_disturb, visibility_class); + + noti_setting->do_not_disturb = do_not_disturb; + noti_setting->visibility_class = visibility_class; + + NOTIFICATION_DBG("system setting2 #### %d, %d", + noti_setting->do_not_disturb, noti_setting->visibility_class); - return status; + return NOTIFICATION_ERROR_NONE; } -int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value) +EXPORT_API GVariant *notification_ipc_make_gvariant_from_setting(struct notification_setting *noti_setting) { - int status = 0; - int ret = 0; - struct packet *packet; - struct packet *result; - - packet = packet_create("set_noti_property", "sss", pkgname, property, value); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "ii", &status, &ret) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; - } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(delete)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; - } + GVariant *body = NULL; + + body = g_variant_new("(siii)", + noti_setting->package_name, + noti_setting->allow_to_notify, + noti_setting->do_not_disturb_except, + noti_setting->visibility_class); - return status; + return body; } -int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value) +EXPORT_API int notification_ipc_make_setting_from_gvariant(struct notification_setting *noti_setting, + GVariant *variant) { - int status = 0; - char *ret = NULL; - struct packet *packet; - struct packet *result; - - packet = packet_create("get_noti_property", "ss", pkgname, property); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (packet_get(result, "is", &status, &ret) != 2) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); - return NOTIFICATION_ERROR_IO_ERROR; - } - if (status == NOTIFICATION_ERROR_NONE && ret != NULL) - *value = strdup(ret); + NOTIFICATION_DBG("notification_ipc_make_setting_from_gvariant !!!!"); + char *pkgname; + int allow_to_notify; + int do_not_disturb_except; + int visibility_class; - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(delete)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + if (noti_setting == NULL || variant == NULL) { + NOTIFICATION_ERR("invalid data"); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } + g_variant_get(variant, + "(&siii)", + &pkgname, + &allow_to_notify, + &do_not_disturb_except, + &visibility_class); + + NOTIFICATION_DBG("setting from variant %s !!", pkgname); + + noti_setting->package_name = _dup_string(pkgname); + noti_setting->allow_to_notify = allow_to_notify; + noti_setting->do_not_disturb_except = do_not_disturb_except; + noti_setting->visibility_class = visibility_class; - return status; + NOTIFICATION_DBG("setting from variant %s, %s", + noti_setting->package_name, pkgname); + + return NOTIFICATION_ERROR_NONE; } -int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag) +static int _send_service_register() +{ + NOTIFICATION_DBG("service register"); + GDBusMessage *reply = NULL; + int result; + + result = _send_sync_noti(NULL, &reply, "noti_service_register"); + + if(reply) + g_object_unref(reply); + + NOTIFICATION_ERR("_send_service_register done = %s, result = %d", _bus_name, result); + return result; +} + +static int _ipc_monitor_register(void) +{ + NOTIFICATION_ERR("register a service\n"); + + return _send_service_register(); +} + +static void _on_name_appeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + NOTIFICATION_DBG("name appeared : %s", name); + is_master_started = 1; + _ipc_monitor_register(); + + /* TODO: dbus activation isn't enough ? */ + _do_deffered_task(); +} + +static void _on_name_vanished(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + NOTIFICATION_DBG("name vanished : %s", name); + is_master_started = 0; +} + +int notification_ipc_monitor_init(void) { - struct packet *packet; - struct packet *result; - - packet = packet_create("load_noti_by_tag", "ss", pkgname, tag); - result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, - packet, - NOTIFICATION_IPC_TIMEOUT); - packet_destroy(packet); - - if (result != NULL) { - if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("Failed to get a result packet"); - packet_unref(result); + int ret; + + ret = _dbus_init(); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init dbus %d", ret); + return ret; + } + + ret = _dbus_signal_init(); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't signal_init %d", ret); + return ret; + } + + ret = _ipc_monitor_register(); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("Can't init ipc_monitor_register %d", ret); + return ret; + } + + if (provider_monitor_id == 0) { + provider_monitor_id = g_bus_watch_name_on_connection( + _gdbus_conn, + PROVIDER_BUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + _on_name_appeared, + _on_name_vanished, + NULL, + NULL); + + if (provider_monitor_id == 0) { + g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id); + monitor_id = 0; + NOTIFICATION_ERR("watch on name fail"); return NOTIFICATION_ERROR_IO_ERROR; } + } - packet_unref(result); - } else { - NOTIFICATION_ERR("failed to receive answer(load noti by tag)"); - if (notification_ipc_is_master_ready() == 1) - return NOTIFICATION_ERROR_PERMISSION_DENIED; - else - return NOTIFICATION_ERROR_SERVICE_NOT_READY; + return NOTIFICATION_ERROR_NONE; +} + +static int _ipc_monitor_deregister(void) +{ + if (provider_monitor_id) { + g_bus_unwatch_name(provider_monitor_id); + provider_monitor_id = 0; + } + + if (monitor_id) { + g_dbus_connection_signal_unsubscribe(_gdbus_conn, monitor_id); + monitor_id = 0; } return NOTIFICATION_ERROR_NONE; } +int notification_ipc_monitor_fini(void) +{ + return _ipc_monitor_deregister(); +} diff --git a/src/notification_list.c b/src/notification_list.c index e7220c7..bd80f40 100755 --- a/src/notification_list.c +++ b/src/notification_list.c @@ -28,6 +28,8 @@ #include <notification_noti.h> #include <notification_debug.h> #include <notification_private.h> +#include <notification_ipc.h> + struct _notification_list { notification_list_h prev; @@ -233,11 +235,12 @@ EXPORT_API int notification_get_list(notification_type_e type, if (list == NULL) return NOTIFICATION_ERROR_INVALID_PARAMETER; - ret = notification_noti_get_grouping_list(type, count, &get_list); + ret = notification_ipc_request_load_noti_grouping_list(type, count, &get_list); if (ret != NOTIFICATION_ERROR_NONE) return ret; - *list = get_list; + if (get_list != NULL) + *list = notification_list_get_head(get_list); return NOTIFICATION_ERROR_NONE; } @@ -255,12 +258,13 @@ EXPORT_API int notification_get_detail_list(const char *pkgname, return NOTIFICATION_ERROR_INVALID_PARAMETER; ret = - notification_noti_get_detail_list(pkgname, group_id, priv_id, count, + notification_ipc_request_load_noti_detail_list(pkgname, group_id, priv_id, count, &get_list); if (ret != NOTIFICATION_ERROR_NONE) return ret; - *list = get_list; + if (get_list != NULL) + *list = notification_list_get_head(get_list); return NOTIFICATION_ERROR_NONE; } diff --git a/src/notification_noti.c b/src/notification_noti.c index e4a117f..2130f05 100755 --- a/src/notification_noti.c +++ b/src/notification_noti.c @@ -38,6 +38,7 @@ #include <notification_private.h> #include <notification_setting.h> #include <notification_setting_internal.h> +#include <notification_setting_service.h> #define NOTI_BURST_DELETE_UNIT 10 @@ -359,7 +360,6 @@ static int _insertion_query_create(notification_h noti, char **query) return NOTIFICATION_ERROR_NONE; } - static int _update_query_create(notification_h noti, char **query) { int i = 0; @@ -742,7 +742,7 @@ static bool _is_allowed_to_notify(const char *caller_package_name) char *package_id = NULL; bool ret = true; - err = notification_setting_get_setting_by_package_name(caller_package_name, &setting); + err = noti_setting_service_get_setting_by_package_name(caller_package_name, &setting); if (err != NOTIFICATION_ERROR_NONE) { /* Retry with package id */ err = _get_package_id_by_app_id(caller_package_name, &package_id); @@ -751,9 +751,9 @@ static bool _is_allowed_to_notify(const char *caller_package_name) NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err); goto out; } else { - err = notification_setting_get_setting_by_package_name(package_id, &setting); + err = noti_setting_service_get_setting_by_package_name(package_id, &setting); if (err != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("notification_setting_get_setting_by_package_name failed [%d]", err); + NOTIFICATION_ERR("noti_setting_service_get_setting_by_package_name failed [%d]", err); goto out; } } @@ -794,8 +794,8 @@ static int _handle_do_not_disturb_option(notification_h noti) } /* Get system setting */ - if ((err = notification_system_setting_load_system_setting(&system_setting)) != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("notification_system_setting_load_system_setting failed [%d]", err); + if ((err = noti_system_setting_load_system_setting(&system_setting)) != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("noti_system_setting_load_system_setting failed [%d]", err); goto out; } @@ -808,7 +808,7 @@ static int _handle_do_not_disturb_option(notification_h noti) if (do_not_disturb) { /* Check exception option of the caller package */ - err = notification_setting_get_setting_by_package_name(noti->caller_pkgname, &setting); + err = noti_setting_service_get_setting_by_package_name(noti->caller_pkgname, &setting); if (err != NOTIFICATION_ERROR_NONE) { /* Retry with package id */ @@ -818,9 +818,9 @@ static int _handle_do_not_disturb_option(notification_h noti) NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err); goto out; } else { - err = notification_setting_get_setting_by_package_name(package_id, &setting); + err = noti_setting_service_get_setting_by_package_name(package_id, &setting); if (err != NOTIFICATION_ERROR_NONE) { - NOTIFICATION_ERR("notification_setting_get_setting_by_package_name failed [%d]", err); + NOTIFICATION_ERR("noti_setting_service_get_setting_by_package_name failed [%d]", err); goto out; } } @@ -899,7 +899,6 @@ EXPORT_API int notification_noti_insert(notification_h noti) if (ret != NOTIFICATION_ERROR_NONE) goto err; - ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); if (ret != SQLITE_OK) { NOTIFICATION_ERR("Insert Query : %s", query); @@ -927,7 +926,6 @@ EXPORT_API int notification_noti_insert(notification_h noti) if (title_key == NULL) title_key = noti->caller_pkgname; - /* Bind query */ ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag); if (ret != NOTIFICATION_ERROR_NONE) { @@ -982,7 +980,7 @@ err: return ret; } -int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id) +EXPORT_API int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id) { int ret = 0; char *query = NULL; @@ -1161,7 +1159,6 @@ EXPORT_API int notification_noti_update(notification_h noti) if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE) NOTIFICATION_WARN("_handle_do_not_disturb_option failed"); - /* Check private ID is exist */ ret = _notification_noti_check_priv_id(noti, db); if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) { @@ -1188,11 +1185,13 @@ EXPORT_API int notification_noti_update(notification_h noti) NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db)); goto err; } + ret = _notification_noti_bind_query_double(stmt, "$progress_size", noti->progress_size); if (ret != NOTIFICATION_ERROR_NONE) { NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db)); goto err; } + ret = _notification_noti_bind_query_double(stmt, "$progress_percentage", noti->progress_percentage); if (ret != NOTIFICATION_ERROR_NONE) { NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db)); @@ -1236,7 +1235,7 @@ EXPORT_API int notification_noti_delete_all(notification_type_e type, const char if (!db) return get_last_result(); - if (pkgname == NULL) { + if (pkgname == NULL || strlen(pkgname) == 0) { if (type != NOTIFICATION_TYPE_NONE) snprintf(query_where, sizeof(query_where), "where type = %d ", type); @@ -1530,11 +1529,11 @@ EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgname, int priv_id, int *num_changes) { sqlite3 *db = NULL; - char query[NOTIFICATION_QUERY_MAX] = { 0, }; + char query[NOTIFICATION_QUERY_MAX] = {0, }; int ret; /* Check pkgname is valid */ - if (pkgname == NULL) + if (pkgname == NULL || strlen(pkgname) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; /* Open DB */ @@ -1546,6 +1545,7 @@ EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgna snprintf(query, sizeof(query), "delete from noti_list " "where caller_pkgname = '%s' and priv_id = %d", pkgname, priv_id); + NOTIFICATION_DBG("%s", query); /* execute DB */ ret = notification_db_exec(db, query, num_changes); @@ -1560,7 +1560,7 @@ EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgna return ret; } -int notification_noti_get_count(notification_type_e type, +EXPORT_API int notification_noti_get_count(notification_type_e type, const char *pkgname, int group_id, int priv_id, int *count) @@ -1691,7 +1691,7 @@ err: return ret; } -int notification_noti_get_grouping_list(notification_type_e type, +EXPORT_API int notification_noti_get_grouping_list(notification_type_e type, int count, notification_list_h * list) @@ -1790,7 +1790,7 @@ err: return ret; } -int notification_noti_get_detail_list(const char *pkgname, +EXPORT_API int notification_noti_get_detail_list(const char *pkgname, int group_id, int priv_id, int count, notification_list_h *list) diff --git a/src/notification_permission.c b/src/notification_permission.c index 5a0709d..ef472c6 100755 --- a/src/notification_permission.c +++ b/src/notification_permission.c @@ -30,34 +30,66 @@ #include <notification_debug.h> #include <notification_ipc.h> #include <notification_private.h> +#include <notification_permission.h> +#include <cynara-client.h> #define NOTIFICATION_DB_ACCESS_READ 0 #define NOTIFICATION_DB_ACCESS_WRITE 1 +#define SMACK_LABEL_LEN 255 -#if 0 -int notification_permission_check_by_pid(const char *noti_pkgname, int pid, int access) +int notification_check_permission() { + cynara *p_cynara; + + int fd = 0; int ret = 0; - char pkgname[512 + 1] = { 0, }; - bool preload = false; - package_manager_compare_result_type_e compare_result; - - /* get pkgname by pid */ - const char *pkgname = aul_app_get_pkgname_bypid(pid); - ret = aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname)); - if (ret == AUL_R_OK) { - if (strcmp(pkgname, noti_pkgname) == 0) - return NOTIFICATION_ERROR_NONE; - - package_manager_is_preload_package_by_app_id(pkgname, &preload); - if (preload == true) - return NOTIFICATION_ERROR_NONE; - - package_manager_compare_package_cert_info(noti_pkgname, &compare_result); - if (compare_result == PACKAGE_MANAGER_COMPARE_MATCH) - return NOTIFICATION_ERROR_NONE; + char subject_label[SMACK_LABEL_LEN + 1] = ""; + char uid[10] = {0,}; + char *client_session = ""; + + static bool checked_privilege = FALSE; + + if (checked_privilege) + return NOTIFICATION_ERROR_NONE; + + ret = cynara_initialize(&p_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) { + LOGE("cannot init cynara [%d] failed!", ret); + ret = NOTIFICATION_ERROR_IO_ERROR; + goto out; + } + + fd = open("/proc/self/attr/current", O_RDONLY); + if (fd < 0) { + LOGE("open [%d] failed!", errno); + ret = NOTIFICATION_ERROR_IO_ERROR; + goto out; } - return NOTIFICATION_ERROR_PERMISSION_DENIED; + ret = read(fd, subject_label, SMACK_LABEL_LEN); + if (ret < 0) { + LOGE("read [%d] failed!", errno); + close(fd); + ret = NOTIFICATION_ERROR_IO_ERROR; + goto out; + } + close(fd); + + snprintf(uid, 10, "%d", getuid()); + ret = cynara_check(p_cynara, subject_label, client_session, uid, + "http://tizen.org/privilege/notification"); + if (ret != CYNARA_API_ACCESS_ALLOWED) { + LOGE("cynara access check [%d] failed!", ret); + ret = NOTIFICATION_ERROR_PERMISSION_DENIED; + goto out; + } + ret = NOTIFICATION_ERROR_NONE; + checked_privilege = TRUE; +out: + + if (p_cynara) + cynara_finish(p_cynara); + + return ret; } -#endif + diff --git a/src/notification_setting.c b/src/notification_setting.c index d54e5ec..fcb07eb 100755 --- a/src/notification_setting.c +++ b/src/notification_setting.c @@ -40,228 +40,27 @@ #define NOTIFICATION_PRIVILEGE "http://tizen.org/privilege/notification" -static int _get_table_field_data_int(char **table, int *buf, int index) -{ - if ((table == NULL) || (buf == NULL) || (index < 0)) { - NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index); - return false; - } - - if (table[index] != NULL) { - *buf = atoi(table[index]); - return true; - } - - *buf = 0; - return false; -} - -static int _get_table_field_data_string(char **table, char **buf, int ucs2, int index) -{ - int ret = false; - - if ((table == NULL) || (buf == NULL) || (index < 0)) { - NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index); - return false; - } - - char *pTemp = table[index]; - int sLen = 0; - if (pTemp == NULL) { - *buf = NULL; - } else { - sLen = strlen(pTemp); - if (sLen) { - *buf = (char *) malloc(sLen + 1); - if (*buf == NULL) { - NOTIFICATION_ERR("malloc is failed"); - goto out; - } - memset(*buf, 0, sLen + 1); - strncpy(*buf, pTemp, sLen); - } else { - *buf = NULL; - } - } - - ret = true; -out: - - return ret; -} - - EXPORT_API int notification_setting_get_setting_array(notification_setting_h *setting_array, int *count) { - int err = NOTIFICATION_ERROR_NONE; - sqlite3 *local_db_handle = NULL; - char *sql_query = NULL; - char **query_result = NULL; - int sql_return; - int row_count = 0; - int column_count = 0; - int i = 0; - int col_index = 0; - notification_setting_h result_setting_array = NULL; - + int ret = NOTIFICATION_ERROR_NONE; if (setting_array == NULL || count == NULL) { NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); - 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); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class " - "FROM %s " - "ORDER BY package_name", NOTIFICATION_SETTING_DB_TABLE); - - if (!sql_query) { - NOTIFICATION_ERR("fail to alloc query"); - 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("NOTIFICATION_ERROR_FROM_DB failed [%d][%s]", sql_return, sql_query); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - if (!row_count) { - NOTIFICATION_DBG("No setting found..."); - err = NOTIFICATION_ERROR_NOT_EXIST_ID; - goto out; - } - - NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); - if (!(result_setting_array = (struct notification_setting*)malloc(sizeof(struct notification_setting) * row_count))) { - NOTIFICATION_ERR("malloc failed..."); - err = NOTIFICATION_ERROR_OUT_OF_MEMORY; - goto out; - } - - col_index = column_count; - - for (i = 0; i < row_count; i++) { - _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++); - _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].allow_to_notify), col_index++); - _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].do_not_disturb_except), col_index++); - _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++); - } - - *setting_array = result_setting_array; - *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); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } - - return err; + ret = notification_ipc_request_get_setting_array(setting_array, count); + return ret; } EXPORT_API int notification_setting_get_setting_by_package_name(const char *package_name, notification_setting_h *setting) { - int err = NOTIFICATION_ERROR_NONE; - sqlite3 *local_db_handle = NULL; - char *sql_query = NULL; - char **query_result = NULL; - int sql_return; - int row_count = 0; - int column_count = 0; - int i = 0; - int col_index = 0; - notification_setting_h result_setting_array = NULL; - + int ret = NOTIFICATION_ERROR_NONE; if (package_name == NULL || setting == NULL) { NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); - 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); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class " - "FROM %s " - "WHERE package_name = %Q ", NOTIFICATION_SETTING_DB_TABLE, package_name); - - if (!sql_query) { - NOTIFICATION_ERR("fail to alloc query"); - 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); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - if (!row_count) { - NOTIFICATION_DBG("No setting found for [%s]", package_name); - err = NOTIFICATION_ERROR_NOT_EXIST_ID; - goto out; - } - - NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); - - row_count = 1; - - if (!(result_setting_array = (struct notification_setting*)malloc(sizeof(struct notification_setting) * row_count))) { - NOTIFICATION_ERR("malloc failed..."); - err = NOTIFICATION_ERROR_OUT_OF_MEMORY; - goto out; - } - - col_index = column_count; - - _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++); - _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].allow_to_notify), col_index++); - _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].do_not_disturb_except), col_index++); - _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++); - - *setting = result_setting_array; - -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); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } - - return err; + ret = notification_ipc_request_get_setting_by_package_name(package_name, setting); + return ret; } EXPORT_API int notification_setting_get_setting(notification_setting_h *setting) @@ -473,7 +272,7 @@ EXPORT_API int notification_setting_db_update(const char *package_name, int allo char *sqlbuf = NULL; int sqlret; - if (package_name == NULL) + if (package_name == NULL || strlen(package_name) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; sqlret = db_util_open(DBPATH, &db, 0); @@ -794,84 +593,14 @@ EXPORT_API int notification_setting_delete_package(const char *package_id) EXPORT_API int notification_system_setting_load_system_setting(notification_system_setting_h *system_setting) { - int err = NOTIFICATION_ERROR_NONE; - sqlite3 *local_db_handle = NULL; - char *sql_query = NULL; - char **query_result = NULL; - int sql_return; - int row_count = 0; - int column_count = 0; - int col_index = 0; - notification_system_setting_h result_system_setting = NULL; - + int ret = NOTIFICATION_ERROR_NONE; if (system_setting == NULL) { NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); - 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); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - sql_query = sqlite3_mprintf("SELECT do_not_disturb, visibility_class " - "FROM %s ", NOTIFICATION_SYSTEM_SETTING_DB_TABLE); - - if (!sql_query) { - NOTIFICATION_ERR("fail to alloc query"); - 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); - err = NOTIFICATION_ERROR_FROM_DB; - goto out; - } - - if (!row_count) { - NOTIFICATION_DBG("No setting found..."); - err = NOTIFICATION_ERROR_NOT_EXIST_ID; - goto out; - } - - NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); - - row_count = 1; - - if (!(result_system_setting = (struct notification_system_setting*)malloc(sizeof(struct notification_system_setting)))) { - NOTIFICATION_ERR("malloc failed..."); - err = NOTIFICATION_ERROR_OUT_OF_MEMORY; - goto out; - } - - col_index = column_count; - - _get_table_field_data_int(query_result, (int*)&(result_system_setting->do_not_disturb), col_index++); - _get_table_field_data_int(query_result, &(result_system_setting->visibility_class), col_index++); - - *system_setting = result_system_setting; - -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); + return NOTIFICATION_ERROR_INVALID_PARAMETER; } + ret = notification_ipc_request_load_system_setting(system_setting); - return err; + return ret; } EXPORT_API int notification_system_setting_update_system_setting(notification_system_setting_h system_setting) @@ -1183,13 +912,13 @@ EXPORT_API int notification_setting_db_set(const char *pkgname, const char *prop int sqlret; const char *column = NULL; - if (!pkgname) + if (!pkgname || strlen(pkgname) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; - if (!property) + if (!property || strlen(property) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; - if (!value) + if (!value || strlen(value) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; column = _get_prop_column(property); @@ -1240,10 +969,10 @@ EXPORT_API int notification_setting_db_get(const char *pkgname, const char *prop int sqlret; const char *column = NULL; - if (!pkgname) + if (!pkgname || strlen(pkgname) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; - if (!property) + if (!property || strlen(property) == 0) return NOTIFICATION_ERROR_INVALID_PARAMETER; if (!value) diff --git a/src/notification_setting_service.c b/src/notification_setting_service.c new file mode 100644 index 0000000..b9bfbab --- /dev/null +++ b/src/notification_setting_service.c @@ -0,0 +1,348 @@ +/* + * libnotification + * + * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> + +#include <sqlite3.h> +#include <db-util.h> +#include <tizen.h> + +#include <notification.h> +#include <notification_db.h> +#include <notification_error.h> +#include <notification_debug.h> +#include <notification_private.h> +#include <notification_setting.h> +#include <notification_setting_internal.h> +#include <notification_setting_service.h> + + +static int _get_table_field_data_int(char **table, int *buf, int index) +{ + if ((table == NULL) || (buf == NULL) || (index < 0)) { + NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + if (table[index] != NULL) { + *buf = atoi(table[index]); + return true; + } + + *buf = 0; + return false; +} + +static int _get_table_field_data_string(char **table, char **buf, int ucs2, int index) +{ + int ret = false; + + if ((table == NULL) || (buf == NULL) || (index < 0)) { + NOTIFICATION_ERR("table[%p], buf[%p], index[%d]", table, buf, index); + return false; + } + + char *pTemp = table[index]; + int sLen = 0; + if (pTemp == NULL) { + *buf = NULL; + } else { + sLen = strlen(pTemp); + if (sLen) { + *buf = (char *) malloc(sLen + 1); + if (*buf == NULL) { + NOTIFICATION_ERR("malloc is failed"); + goto out; + } + memset(*buf, 0, sLen + 1); + strncpy(*buf, pTemp, sLen); + } else { + *buf = NULL; + } + } + + ret = true; +out: + + return ret; +} + +EXPORT_API int noti_setting_service_get_setting_by_package_name(const char *package_name, notification_setting_h *setting) +{ + int err = NOTIFICATION_ERROR_NONE; + sqlite3 *local_db_handle = NULL; + char *sql_query = NULL; + char **query_result = NULL; + int sql_return; + int row_count = 0; + int column_count = 0; + int i = 0; + int col_index = 0; + notification_setting_h result_setting_array = NULL; + + if (package_name == NULL || setting == NULL) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); + 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); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class " + "FROM %s " + "WHERE package_name = %Q ", NOTIFICATION_SETTING_DB_TABLE, package_name); + + if (!sql_query) { + NOTIFICATION_ERR("fail to alloc query"); + 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); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + if (!row_count) { + NOTIFICATION_DBG("No setting found for [%s]", package_name); + err = NOTIFICATION_ERROR_NOT_EXIST_ID; + goto out; + } + + NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); + + row_count = 1; + + if (!(result_setting_array = (struct notification_setting*)malloc(sizeof(struct notification_setting) * row_count))) { + NOTIFICATION_ERR("malloc failed..."); + err = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto out; + } + + col_index = column_count; + + _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++); + _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].allow_to_notify), col_index++); + _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].do_not_disturb_except), col_index++); + _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++); + + *setting = result_setting_array; + +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); + } + + return err; +} + + + +EXPORT_API int noti_setting_get_setting_array(notification_setting_h *setting_array, int *count) +{ + int err = NOTIFICATION_ERROR_NONE; + sqlite3 *local_db_handle = NULL; + char *sql_query = NULL; + char **query_result = NULL; + int sql_return; + int row_count = 0; + int column_count = 0; + int i = 0; + int col_index = 0; + notification_setting_h result_setting_array = NULL; + + if (setting_array == NULL || count == NULL) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); + 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); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + sql_query = sqlite3_mprintf("SELECT package_name, allow_to_notify, do_not_disturb_except, visibility_class " + "FROM %s " + "ORDER BY package_name", NOTIFICATION_SETTING_DB_TABLE); + + if (!sql_query) { + NOTIFICATION_ERR("fail to alloc query"); + 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("NOTIFICATION_ERROR_FROM_DB failed [%d][%s]", sql_return, sql_query); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + if (!row_count) { + NOTIFICATION_DBG("No setting found..."); + err = NOTIFICATION_ERROR_NOT_EXIST_ID; + goto out; + } + + NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); + if (!(result_setting_array = (struct notification_setting*)malloc(sizeof(struct notification_setting) * row_count))) { + NOTIFICATION_ERR("malloc failed..."); + err = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto out; + } + + col_index = column_count; + + for (i = 0; i < row_count; i++) { + _get_table_field_data_string(query_result, &(result_setting_array[i].package_name), 1, col_index++); + _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].allow_to_notify), col_index++); + _get_table_field_data_int(query_result, (int*)&(result_setting_array[i].do_not_disturb_except), col_index++); + _get_table_field_data_int(query_result, &(result_setting_array[i].visibility_class), col_index++); + } + + *setting_array = result_setting_array; + *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); + } + + return err; +} + + +EXPORT_API int noti_system_setting_load_system_setting(notification_system_setting_h *system_setting) +{ + int err = NOTIFICATION_ERROR_NONE; + sqlite3 *local_db_handle = NULL; + char *sql_query = NULL; + char **query_result = NULL; + int sql_return; + int row_count = 0; + int column_count = 0; + int col_index = 0; + notification_system_setting_h result_system_setting = NULL; + + if (system_setting == NULL) { + NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER"); + 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); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + sql_query = sqlite3_mprintf("SELECT do_not_disturb, visibility_class " + "FROM %s ", NOTIFICATION_SYSTEM_SETTING_DB_TABLE); + + if (!sql_query) { + NOTIFICATION_ERR("fail to alloc query"); + 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); + err = NOTIFICATION_ERROR_FROM_DB; + goto out; + } + + if (!row_count) { + NOTIFICATION_DBG("No setting found..."); + err = NOTIFICATION_ERROR_NOT_EXIST_ID; + goto out; + } + + NOTIFICATION_DBG("row_count [%d] column_count [%d]", row_count, column_count); + + row_count = 1; + + if (!(result_system_setting = (struct notification_system_setting*)malloc(sizeof(struct notification_system_setting)))) { + NOTIFICATION_ERR("malloc failed..."); + err = NOTIFICATION_ERROR_OUT_OF_MEMORY; + goto out; + } + + col_index = column_count; + + _get_table_field_data_int(query_result, (int*)&(result_system_setting->do_not_disturb), col_index++); + _get_table_field_data_int(query_result, &(result_system_setting->visibility_class), col_index++); + + *system_setting = result_system_setting; + +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); + } + + return err; +} + + + + |