From: Jiwoong Im Date: Wed, 27 Apr 2016 12:32:07 +0000 (+0900) Subject: merge async api from tizen 2.4 X-Git-Tag: accepted/tizen/common/20160428.144908^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85024fa7e299887a0ca2fb4e3048c74d537aee05;p=platform%2Fcore%2Fappfw%2Falarm-manager.git merge async api from tizen 2.4 - alarmmgr_set_systime_async - alarmmgr_set_systime_with_propagation_delay_async Change-Id: I37ecfcbb4207478df698497a0cd80090db664973 Signed-off-by: Jiwoong Im --- diff --git a/include/alarm-internal.h b/include/alarm-internal.h index 69c9c4e..6214b6c 100644 --- a/include/alarm-internal.h +++ b/include/alarm-internal.h @@ -91,6 +91,17 @@ typedef struct { alarm_repeat_mode_t repeat; /**< repeat mode */ } alarm_mode_t; +typedef struct { + alarm_set_time_cb_t callback; + void *user_data; + GDBusProxy *proxy; +} alarm_set_time_data_t; + +enum async_param_type { + SET_SYSTIME = 0, + SET_SYSTIME_WITH_PROPAGATION_DELAY, +}; + /** * This enumeration has alarm type @@ -137,9 +148,11 @@ bool _load_alarms_from_registry(); bundle *_send_alarm_get_appsvc_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code); bool _send_alarm_set_rtc_time(alarm_context_t context, alarm_date_t *time, int *error_code); bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, int *error_code); +bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, alarm_set_time_cb_t result_cb, void *user_data); bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code); bool _send_alarm_create_periodic(alarm_context_t context, int interval, int is_ref, int method, alarm_id_t *alarm_id, int *error_code); bool _send_alarm_set_time(alarm_context_t context, int new_time, int *error_code); +bool _send_alarm_set_time_async(alarm_context_t context, int new_time, alarm_set_time_cb_t result_cb, void *user_data); bool _send_alarm_set_global(alarm_context_t context, int alarm_id, bool global, int *error_code); bool _send_alarm_get_global(alarm_context_t context, int alarm_id, bool *global, int *error_code); diff --git a/include/alarm.h b/include/alarm.h index 0edd294..1bbc389 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -165,6 +165,8 @@ typedef int alarm_id_t; * The prototype of alarm handler. * param [in] alarm_id the id of expired alarm */ +typedef int (*alarm_set_time_cb_t) (int result, void *user_param); + typedef int (*alarm_cb_t) (alarm_id_t alarm_id, void *user_param); typedef int (*alarm_enum_fn_t) (alarm_id_t alarm_id, void *user_param); @@ -1380,6 +1382,19 @@ int alarmmgr_set_rtc_time(alarm_date_t *time); int alarmmgr_set_systime(int new_time); /** + * This function asynchronously changes the system time which tranferred by other module + * @param [in] new_time epoch time to be set + * @param [in] result_cb The asynchronous callback function to get the result + * @param [in] user_param User parameter to be passed to the callback function + * + * @return @c ALARMMGR_RESULT_SUCCESS on success, + * otherwise a negative error value + * @retval #ALARMMGR_RESULT_SUCCESS Successful + * @retval #ERR_ALARM_SYSTEM_FAIL System failure + */ +int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param); + +/** * This function changes the system time and compensates the time using propagation delay. * @param [in] new_time system time to be set (seconds, nanoseconds) * @param [in] req_time time to request to change the system time (seconds, nanoseconds) @@ -1393,6 +1408,21 @@ int alarmmgr_set_systime(int new_time); int alarmmgr_set_systime_with_propagation_delay(struct timespec new_time, struct timespec req_time); /** + * This function asynchronously changes the system time and compensates the time using propagation delay. + * @param [in] new_time system time to be set (seconds, nanoseconds) + * @param [in] req_time time to request to change the system time (seconds, nanoseconds) + * @param [in] result_cb The asynchronous callback function to get the result + * @param [in] user_param User parameter to be passed to the callback function + * + * @return @c ALARMMGR_RESULT_SUCCESS on success, + * otherwise a negative error value + * @retval #ALARMMGR_RESULT_SUCCESS Successful + * @retval #ERR_ALARM_SYSTEM_FAIL System failure + * @retval #ERR_ALARM_INVALID_PARAM invalid parameter + */ +int alarmmgr_set_systime_with_propagation_delay_async(struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_param); + +/** * This function changes the timezone which tranferred by other module * @param [in] tzpath_str the path to timezone definition file * diff --git a/src/alarm-lib-stub.c b/src/alarm-lib-stub.c index f655e5f..d02d7b5 100644 --- a/src/alarm-lib-stub.c +++ b/src/alarm-lib-stub.c @@ -550,6 +550,44 @@ bool _send_alarm_set_time(alarm_context_t context, int new_time, int *error_code return true; } +static void _alarm_set_time_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + int return_code = 0; + GError *error = NULL; + alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; + + if (!alarm_manager_call_alarm_set_time_finish((AlarmManager *)func_data->proxy, + (gint *)&return_code, + res, &error)) { + ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); + g_error_free(error); + return_code = ERR_ALARM_SYSTEM_FAIL; + } + + if (func_data->callback != NULL) + func_data->callback(return_code, func_data->user_data); +} + +bool _send_alarm_set_time_async(alarm_context_t context, int new_time, alarm_set_time_cb_t result_cb, void *user_data) +{ + alarm_set_time_data_t *func_data; + + func_data = g_try_new0(alarm_set_time_data_t, 1); + + if (func_data == NULL) + return false; + + func_data->callback = result_cb; + func_data->user_data = user_data; + func_data->proxy = context.proxy; + + alarm_manager_call_alarm_set_time((AlarmManager *)context.proxy, new_time, + NULL, _alarm_set_time_cb, func_data); + + return true; +} + bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, int *error_code) { GError *error = NULL; @@ -579,6 +617,45 @@ bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, unsign return true; } +static void _alarm_set_time_with_delay_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + int return_code = 0; + GError *error = NULL; + alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; + + if (!alarm_manager_call_alarm_set_time_with_propagation_delay_finish((AlarmManager *)func_data->proxy, + (gint *)&return_code, + res, &error)) { + ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); + g_error_free(error); + return_code = ERR_ALARM_SYSTEM_FAIL; + } + + if (func_data->callback != NULL) + func_data->callback(return_code, func_data->user_data); +} + +bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, alarm_set_time_cb_t result_cb, void *user_data) +{ + alarm_set_time_data_t *func_data; + + func_data = g_try_new0(alarm_set_time_data_t, 1); + + if (func_data == NULL) + return false; + + func_data->callback = result_cb; + func_data->user_data = user_data; + func_data->proxy = context.proxy; + + alarm_manager_call_alarm_set_time_with_propagation_delay((AlarmManager *)context.proxy, + new_sec, new_nsec, req_sec, req_nsec, + NULL, _alarm_set_time_with_delay_cb, func_data); + + return true; +} + bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code) { GError *error = NULL; diff --git a/src/alarm-lib.c b/src/alarm-lib.c index 4b4825b..3f3a0a3 100644 --- a/src/alarm-lib.c +++ b/src/alarm-lib.c @@ -44,7 +44,7 @@ static alarm_context_t alarm_context = { NULL, NULL, 0, NULL, NULL, -1 }; static bool b_initialized = false; static bool sub_initialized = false; -pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; static void __handle_expired_signal(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, @@ -62,6 +62,13 @@ typedef struct _alarm_cb_info_t { struct _alarm_cb_info_t *next; } alarm_cb_info_t; +struct alarm_async_param_t { + enum async_param_type type; + GVariant *v; + alarm_set_time_cb_t result_cb; + void *user_param; +}; + static alarm_cb_info_t *alarmcb_head = NULL; static void __add_resultcb(alarm_id_t alarm_id, alarm_cb_t cb_func, void *data) @@ -296,6 +303,80 @@ out: return _return; } +static int __alarm_context_init() +{ + int fd = 0; + int ret = 0; + + if (sub_initialized) + return ALARMMGR_RESULT_SUCCESS; + + alarm_context.proxy = g_dbus_proxy_new_sync(alarm_context.connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION, + NULL, + "org.tizen.alarm.manager", + "/org/tizen/alarm/manager", + "org.tizen.alarm.manager", + NULL, + NULL); + + if (alarm_context.proxy == NULL) { + ALARM_MGR_EXCEPTION_PRINT("Creating a proxy is failed."); + g_object_unref(alarm_context.connection); + return ERR_ALARM_SYSTEM_FAIL; + } + + sub_initialized = true; + + return ALARMMGR_RESULT_SUCCESS; +} + +static void __bus_get_for_async_api(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + struct alarm_async_param_t *param = (struct alarm_async_param_t *)user_data; + + pthread_mutex_lock(&init_lock); + + alarm_context.connection = g_bus_get_finish(res, &error); + if (!alarm_context.connection) { + ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); + g_error_free(error); + g_variant_unref(param->v); + g_free(param); + pthread_mutex_unlock(&init_lock); + return; + } + + if (__alarm_context_init() != ALARMMGR_RESULT_SUCCESS) { + g_variant_unref(param->v); + g_free(param); + pthread_mutex_unlock(&init_lock); + return; + } + + if (param->type == SET_SYSTIME_WITH_PROPAGATION_DELAY) { + struct timespec new_time; + struct timespec req_time; + g_variant_get(param->v, "(uuuu)", &new_time.tv_sec, &new_time.tv_nsec, + &req_time.tv_sec, &req_time.tv_nsec); + _send_alarm_set_time_with_propagation_delay_async(alarm_context, + new_time.tv_sec, new_time.tv_nsec, + req_time.tv_sec, req_time.tv_nsec, + param->result_cb, param->user_param); + } else if (param->type == SET_SYSTIME) { + int new_time; + g_variant_get(param->v, "i", &new_time); + _send_alarm_set_time_async(alarm_context, new_time, + param->result_cb, param->user_param); + } + + g_variant_unref(param->v); + g_free(param); + pthread_mutex_unlock(&init_lock); +} + static int __sub_init() { GError *error = NULL; @@ -324,24 +405,7 @@ static int __sub_init() return ERR_ALARM_SYSTEM_FAIL; } - alarm_context.proxy = g_dbus_proxy_new_sync(alarm_context.connection, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.tizen.alarm.manager", - "/org/tizen/alarm/manager", - "org.tizen.alarm.manager", - NULL, - NULL); - - if (alarm_context.proxy == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Creating a proxy is failed."); - g_object_unref(alarm_context.connection); - pthread_mutex_unlock(&init_lock); - return ERR_ALARM_SYSTEM_FAIL; - } - - sub_initialized = true; - + ret = __alarm_context_init(); pthread_mutex_unlock(&init_lock); return ALARMMGR_RESULT_SUCCESS; @@ -1464,6 +1528,35 @@ EXPORT_API int alarmmgr_set_systime(int new_time) return ALARMMGR_RESULT_SUCCESS; } +EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param) +{ + int error_code; + struct alarm_async_param_t *param; + + ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_systime(%d) is called.", new_time); + + if (sub_initialized) { + if (!_send_alarm_set_time_async(alarm_context, new_time, + result_cb, user_param)) + return ERR_ALARM_SYSTEM_FAIL; + } else { +#if !(GLIB_CHECK_VERSION(2, 32, 0)) + g_thread_init(NULL); +#endif +#if !(GLIB_CHECK_VERSION(2, 36, 0)) + g_type_init(); +#endif + param = g_try_new0(struct alarm_async_param_t, 1); + param->type = SET_SYSTIME; + param->v = g_variant_new("i", new_time); + param->result_cb = result_cb; + param->user_param = user_param; + g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param); + } + + return ALARMMGR_RESULT_SUCCESS; +} + EXPORT_API int alarmmgr_set_systime_with_propagation_delay(struct timespec new_time, struct timespec req_time) { int error_code; @@ -1482,6 +1575,38 @@ EXPORT_API int alarmmgr_set_systime_with_propagation_delay(struct timespec new_t return ALARMMGR_RESULT_SUCCESS; } +EXPORT_API int alarmmgr_set_systime_with_propagation_delay_async(struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_param) +{ + int error_code; + struct alarm_async_param_t *param; + + ALARM_MGR_LOG_PRINT("[alarm-lib] New: %d(sec) %09d(nsec), Requested: %d(sec) %09d(nsec)", + new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec); + + if (sub_initialized) { + if (!_send_alarm_set_time_with_propagation_delay_async(alarm_context, + new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, + req_time.tv_nsec, result_cb, user_param)) + return ERR_ALARM_SYSTEM_FAIL; + } else { +#if !(GLIB_CHECK_VERSION(2, 32, 0)) + g_thread_init(NULL); +#endif +#if !(GLIB_CHECK_VERSION(2, 36, 0)) + g_type_init(); +#endif + param = g_try_new0(struct alarm_async_param_t, 1); + param->type = SET_SYSTIME_WITH_PROPAGATION_DELAY; + param->v = g_variant_new("(uuuu)", new_time.tv_sec, new_time.tv_nsec, + req_time.tv_sec, req_time.tv_nsec); + param->result_cb = result_cb; + param->user_param = user_param; + g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param); + } + + return ALARMMGR_RESULT_SUCCESS; +} + EXPORT_API int alarmmgr_set_timezone(char *tzpath_str) { int error_code;