X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=client%2Fstt.c;h=149ac44a692772f55d7e008d2bbd2dd08ab5db2d;hb=f744e25a4a0ad43d1889ccf9216eddd5a1f148d2;hp=faf821f3266bb65f28c0fc4f507cf9a54805a0d3;hpb=bde92c5b26e92f7564e8d3a24c53b38e983d5968;p=platform%2Fcore%2Fuifw%2Fstt.git diff --git a/client/stt.c b/client/stt.c index faf821f..149ac44 100644 --- a/client/stt.c +++ b/client/stt.c @@ -30,6 +30,7 @@ #include "stt_client.h" #include "stt_dbus.h" #include "stt_config_mgr.h" +#include "stt_internal.h" #include "stt_main.h" @@ -229,6 +230,33 @@ void __stt_config_lang_changed_cb(const char* before_language, const char* curre return; } +static Eina_Bool __reconnect_by_engine_changed(void *data) +{ + stt_h stt = (stt_h)data; + + stt_client_s* client = stt_client_get(stt); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid"); + return EINA_FALSE; + } + + if (STT_STATE_READY != client->current_state) { + usleep(10000); + return EINA_TRUE; + } + + int ret = stt_unprepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + ret = stt_prepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + + return EINA_FALSE; +} + void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, bool support_silence, bool need_credential, void* user_data) { stt_h stt = (stt_h)user_data; @@ -244,6 +272,29 @@ void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, if (NULL != language) SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language); SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need"); + /* When the default engine is changed, please unload the old engine and load the new one. */ + int ret = -1; + + if (NULL == client->current_engine_id) { + if (STT_STATE_RECORDING == client->current_state || STT_STATE_PROCESSING == client->current_state) { + ret = stt_cancel(stt); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] STT client canceling..."); + } + + ecore_idler_add(__reconnect_by_engine_changed, (void*)stt); + } else if (STT_STATE_READY == client->current_state) { + ret = stt_unprepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + ret = stt_prepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + } + } + /* call callback function */ if (NULL != client->engine_changed_cb) { client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data); @@ -673,6 +724,11 @@ int stt_set_private_data(stt_h stt, const char* key, const char* data) return STT_ERROR_INVALID_STATE; } + if (true != client->internal && (0 == strcmp(key, "server") || 0 == strcmp(key, "rampcode") || 0 == strcmp(key, "epd"))) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This is not an internal app"); + return STT_ERROR_INVALID_PARAMETER; + } + int ret = -1; int count = 0; while (0 != ret) { @@ -755,6 +811,69 @@ int stt_get_private_data(stt_h stt, const char* key, char** data) return STT_ERROR_NONE; } + +int stt_set_server_stt(stt_h stt, const char* key, char* user_data) +{ + int ret = -1; + stt_client_s* client = NULL; + + if (0 != __stt_get_feature_enabled()) { + return STT_ERROR_NOT_SUPPORTED; + } + if (0 != __stt_check_privilege()) { + return STT_ERROR_PERMISSION_DENIED; + } + if (0 != __stt_check_handle(stt, &client)) { + return STT_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_DEBUG, TAG_STTC, "===== Set STT server"); + + if (NULL == key || NULL == user_data) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter"); + return STT_ERROR_INVALID_PARAMETER; + } + + if (STT_STATE_CREATED != client->current_state && STT_STATE_READY != client->current_state) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] The current state is invalid (%d).", client->current_state); + return STT_ERROR_INVALID_STATE; + } + + + client->internal = true; + + char* private_key = NULL; + private_key = strdup(key); + if (NULL == private_key) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(private_key)"); + return STT_ERROR_OUT_OF_MEMORY; + } + + char* data = NULL; + data = strdup(user_data); + if (NULL == data) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(data)"); + free(private_key); + private_key = NULL; + return STT_ERROR_OUT_OF_MEMORY; + } + + ret = stt_set_private_data(stt, private_key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data, ret(%d), key(%s)", ret, private_key); + } + + free(data); + data = NULL; + free(private_key); + private_key = NULL; + + SLOG(LOG_DEBUG, TAG_STTC, "======"); + SLOG(LOG_DEBUG, TAG_STTC, " "); + + return ret; +} + static Eina_Bool __stt_connect_daemon(void *data) { stt_client_s* client = (stt_client_s*)data; @@ -1725,34 +1844,81 @@ static Eina_Bool __stt_notify_error(void *data) int __stt_cb_error(int uid, int reason, char* err_msg) { - stt_client_s* client = stt_client_get_by_uid(uid); - if (NULL == client) { - SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); - return -1; - } + if (-1 == uid) { + GList* client_list = NULL; + client_list = stt_client_get_client_list(); - client->reason = reason; - client->internal_state = STT_INTERNAL_STATE_NONE; - if (NULL != client->err_msg) { - free(client->err_msg); - client->err_msg = NULL; - } - client->err_msg = strdup(err_msg); + GList *iter = NULL; + stt_client_s *data = NULL; - SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); + if (g_list_length(client_list) > 0) { + /* Get a first item */ + iter = g_list_first(client_list); - if (NULL != client->error_cb) { - ecore_timer_add(0, __stt_notify_error, client); + while (NULL != iter) { + data = iter->data; + + data->reason = reason; + data->internal_state = STT_INTERNAL_STATE_NONE; + if (NULL != data->err_msg) { + free(data->err_msg); + data->err_msg = NULL; + } + if (NULL != err_msg) + data->err_msg = strdup(err_msg); + + SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); + + if (NULL != data->error_cb) { + ecore_timer_add(0, __stt_notify_error, data); + } else { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); + } + + if (STT_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + + data->current_state = STT_STATE_CREATED; + if (0 != stt_prepare(data->stt)) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + } + } + + /* Next item */ + iter = g_list_next(iter); + } + } } else { - SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); - } + stt_client_s* client = stt_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); + return -1; + } + + client->reason = reason; + client->internal_state = STT_INTERNAL_STATE_NONE; + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + if (NULL != err_msg) + client->err_msg = strdup(err_msg); - if (STT_ERROR_SERVICE_RESET == reason) { - SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); - client->current_state = STT_STATE_CREATED; - if (0 != stt_prepare(client->stt)) { - SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + if (NULL != client->error_cb) { + ecore_timer_add(0, __stt_notify_error, client); + } else { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); + } + + if (STT_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + + client->current_state = STT_STATE_CREATED; + if (0 != stt_prepare(client->stt)) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + } } } @@ -1936,6 +2102,46 @@ int __stt_cb_set_state(int uid, int state) return 0; } +static void __stt_notify_speech_status(void *data) +{ + stt_client_s* client = (stt_client_s*)data; + + /* check handle */ + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify speech status : A handle is not valid"); + return; + } + + if (NULL == stt_client_get_by_uid(client->uid)) { + return; + } + + if (NULL != client->speech_status_cb) { + stt_client_use_callback(client); + client->speech_status_cb(client->stt, client->speech_status, client->speech_status_user_data); + stt_client_not_use_callback(client); + SLOG(LOG_DEBUG, TAG_STTC, "Speech status callback is called"); + } else { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Speech status callback is null"); + } + + return; +} + +int __stt_cb_speech_status(int uid, int status) +{ + stt_client_s* client = stt_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); + return -1; + } + + client->speech_status = status; + + ecore_main_loop_thread_safe_call_async(__stt_notify_speech_status, client); + return 0; +} + int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data) { stt_client_s* client = NULL; @@ -2190,3 +2396,54 @@ int stt_unset_engine_changed_cb(stt_h stt) return 0; } + +int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data) +{ + stt_client_s* client = NULL; + if (0 != __stt_get_feature_enabled()) { + return STT_ERROR_NOT_SUPPORTED; + } + if (0 != __stt_check_privilege()) { + return STT_ERROR_PERMISSION_DENIED; + } + if (0 != __stt_check_handle(stt, &client)) { + return STT_ERROR_INVALID_PARAMETER; + } + + if (NULL == callback) + return STT_ERROR_INVALID_PARAMETER; + + if (STT_STATE_CREATED != client->current_state) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state); + return STT_ERROR_INVALID_STATE; + } + + client->speech_status_cb = callback; + client->speech_status_user_data = user_data; + + return 0; +} + +int stt_unset_speech_status_cb(stt_h stt) +{ + stt_client_s* client = NULL; + if (0 != __stt_get_feature_enabled()) { + return STT_ERROR_NOT_SUPPORTED; + } + if (0 != __stt_check_privilege()) { + return STT_ERROR_PERMISSION_DENIED; + } + if (0 != __stt_check_handle(stt, &client)) { + return STT_ERROR_INVALID_PARAMETER; + } + + if (STT_STATE_CREATED != client->current_state) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state); + return STT_ERROR_INVALID_STATE; + } + + client->speech_status_cb = NULL; + client->speech_status_user_data = NULL; + + return 0; +}