static Ecore_Timer* g_check_state_timer = NULL;
static Ecore_Timer* g_notify_error_timer = NULL;
-static Ecore_Timer* g_prepare_timer = NULL;
/* for repetition */
static char* g_language = NULL;
static int g_voice_type = -1;
static int g_speed = -1;
-static int g_retry_cnt = 0;
/* for checking engine update */
static pkgmgr_client* g_pkgmgr = NULL;
static char* g_pkgmgr_status = NULL;
-static char* g_engine_name = NULL;
-static char g_engine_appid[256];
static int g_engine_update_status = 0;
static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
static Ecore_Thread* g_pkgmgr_thread = NULL;
static volatile bool g_is_finished_pkgmgr_thread = false;
-static bool __is_engine_launched(const char* appid);
/* Function definition */
static Eina_Bool __tts_notify_state_changed(void *data);
static Eina_Bool __tts_notify_error(void *data);
int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg);
-int __tts_recheck_screen_reader();
static void __start_reprepare_thread(void* data, Ecore_Thread* thread);
static void __end_reprepare_thread(void* data, Ecore_Thread* thread);
static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread);
return code;
}
+static int __tts_recheck_screen_reader()
+{
+ SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Check screen reader again");
+
+ int ret = -1;
+ int screen_reader = 0;
+
+ ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
+ return TTS_ERROR_INVALID_STATE;
+ } else {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
+ g_screen_reader = (bool)screen_reader;
+ }
+
+ return TTS_ERROR_NONE;
+}
+
//LCOV_EXCL_START
void __tts_config_voice_changed_cb(const char* before_lang, int before_voice_type, const char* language, int voice_type, bool auto_voice, void* user_data)
{
// type (the type of the pkgname)
SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
- if (NULL == g_engine_name) {
+ const char* engine_name = tts_core_get_engine_name();
+ if (NULL == engine_name) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
return 0;
}
- if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
+ if (0 != strncmp(engine_name, pkgname, strlen(engine_name))) {
SLOG(LOG_DEBUG, TAG_TTSC, "[WARN] this is not tts engine");
return 0;
} else {
if (key) {
if (0 == strncmp(key, "start", strlen(key))) {
- if (NULL != g_pkgmgr_status) {
- free(g_pkgmgr_status);
- g_pkgmgr_status = NULL;
- }
+ if (NULL != g_pkgmgr_status) {
+ free(g_pkgmgr_status);
+ g_pkgmgr_status = NULL;
+ }
- if (val) {
- g_pkgmgr_status = strdup(val);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
+ if (val) {
+ g_pkgmgr_status = strdup(val);
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
- if ((0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
- g_engine_update_status = 1;
- }
- }
+ if ((0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
+ g_engine_update_status = 1;
+ }
+ }
} else if (0 == strncmp(key, "end", strlen(key)) && val && 0 == strncmp(val, "ok", strlen(val))) {
if (g_pkgmgr_status) {
if (0 == strncmp(g_pkgmgr_status, "install", strlen(g_pkgmgr_status)) || 0 == strncmp(g_pkgmgr_status, "update", strlen(g_pkgmgr_status))) {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
- g_engine_update_status = 0;
+ SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
+ g_engine_update_status = 0;
free(g_pkgmgr_status);
g_pkgmgr_status = NULL;
return ;
}
-static void __tts_get_engine_appid(tts_client_s* client, char* engine_name, char** engine_appid)
-{
- char temp[256];
- memset(temp, '\0', 256);
-
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- return;
- }
-
- if (TTS_MODE_DEFAULT == client->mode) {
- snprintf(temp, 256, "%s", engine_name);
- } else if (TTS_MODE_NOTIFICATION == client->mode) {
- snprintf(temp, 256, "%s-noti", engine_name);
- } else if (TTS_MODE_SCREEN_READER == client->mode) {
- snprintf(temp, 256, "%s-sr", engine_name);
- } else if (TTS_MODE_INTERRUPT == client->mode) {
- snprintf(temp, 256, "%s-interrupt", engine_name);
- }
- *engine_appid = strdup(temp);
- return;
-}
-
static void __tts_config_engine_changed_cb(keynode_t* key, void* data)
{
SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
- tts_h temp = (tts_h)data;
-
- g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
- if (NULL == g_engine_name) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
+ if (0 != tts_core_update_engine_name()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
return;
- } else {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
}
- memset(g_engine_appid, '\0', 256);
-
- tts_client_s* client = tts_client_get(temp);
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- snprintf(g_engine_appid, 256, "%s", g_engine_name);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] default tts engine name(%s), appid(%s)", g_engine_name, g_engine_appid);
- return ;
- }
-
- char* engine_appid = NULL;
- __tts_get_engine_appid(client, g_engine_name, &engine_appid);
- if (engine_appid) {
- snprintf(g_engine_appid, 256, "%s", engine_appid);
- free(engine_appid);
- }
-
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine name(%s), appid(%s)", g_engine_name, g_engine_appid);
-
return;
}
SLOG(LOG_INFO, TAG_TTSC, "[INFO] call ecore thread for creating pkgmgr thread");
- g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
- if (NULL == g_engine_name) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
- } else {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
- }
-
- memset(g_engine_appid, '\0', 256);
- if (NULL != g_engine_name) {
- snprintf(g_engine_appid, 256, "%s", g_engine_name);
-
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] engine appid(%s)", g_engine_appid);
+ if (0 != tts_core_update_engine_name()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
+ return TTS_ERROR_OPERATION_FAILED;
}
/* Register vconfkey callback to detect engine change */
vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __tts_config_engine_changed_cb, client->tts);
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
- SLOG(LOG_DEBUG, TAG_TTSC, " ");
return TTS_ERROR_NONE;
}
client->current_state = TTS_STATE_CREATED;
case TTS_STATE_CREATED:
- if (NULL != client->conn_timer) {
- SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
- ecore_timer_del(client->conn_timer);
- client->conn_timer = NULL;
- }
/* Unset registered callbacks */
__tts_unset_all_callbacks(tts);
ecore_timer_del(g_notify_error_timer);
g_notify_error_timer = NULL;
}
- /* Delete prepare timer before destroying handle */
- if (NULL != g_prepare_timer) {
- ecore_timer_del(g_prepare_timer);
- g_prepare_timer = NULL;
- }
-
tts = NULL;
tts_config_unset_screen_reader_callback(client->uid);
}
- memset(g_engine_appid, '\0', 256);
- if (TTS_MODE_DEFAULT == mode) {
- snprintf(g_engine_appid, 256, "%s", g_engine_name);
- } else if (TTS_MODE_NOTIFICATION == mode) {
- snprintf(g_engine_appid, 256, "%s-noti", g_engine_name);
- } else if (TTS_MODE_SCREEN_READER == mode) {
- snprintf(g_engine_appid, 256, "%s-sr", g_engine_name);
- } else if (TTS_MODE_INTERRUPT == mode) {
- snprintf(g_engine_appid, 256, "%s-interrupt", g_engine_name);
- }
-
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] engine appid(%s)", g_engine_appid);
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NONE;
}
// LCOV_EXCL_STOP
-static Eina_Bool __tts_connect_daemon(void *data)
-{
- tts_h tts = (tts_h)data;
- tts_client_s* client = tts_client_get(tts);
-
- /* check handle */
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- return EINA_FALSE;
- }
-
- bool is_launched = __is_engine_launched(g_engine_appid);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
-
- if (false == is_launched) {
- /* check whether engine is updating or not */
- if (g_engine_update_status) {
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
- if (NULL == client->thread) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
- client->thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, tts);
- }
- return EINA_FALSE;
- }
- }
-
- /* Send hello */
- if (0 != tts_dbus_request_hello_sync(client->uid)) {
- return EINA_TRUE;
- }
-
- SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
-
- /* do request initialize */
- int ret = -1;
- bool credential_needed = false;
-
- ret = tts_dbus_request_initialize(client->uid, &credential_needed);
-
- if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
-
- client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
- client->utt_id = -1;
-
- if (NULL != g_notify_error_timer) {
- ecore_timer_del(g_notify_error_timer);
- g_notify_error_timer = NULL;
- }
- g_notify_error_timer = ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
-
- if (client->conn_timer) {
- ecore_timer_del(client->conn_timer);
- client->conn_timer = NULL;
- }
- return EINA_FALSE;
-
- } else if (TTS_ERROR_PERMISSION_DENIED == ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
-
- client->reason = TTS_ERROR_PERMISSION_DENIED;
- client->utt_id = -1;
-
- if (NULL != g_notify_error_timer) {
- ecore_timer_del(g_notify_error_timer);
- g_notify_error_timer = NULL;
- }
- g_notify_error_timer = ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
-
- if (client->conn_timer) {
- ecore_timer_del(client->conn_timer);
- client->conn_timer = NULL;
- }
- return EINA_FALSE;
-
- } else if (TTS_ERROR_NONE != ret) {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
- return EINA_TRUE;
-
- } else {
- /* success to connect tts-daemon */
- client->credential_needed = credential_needed;
- SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
- }
-
- if (client->conn_timer) {
- ecore_timer_del(client->conn_timer);
- client->conn_timer = NULL;
- }
-
- client = tts_client_get(tts);
- /* check handle */
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- return EINA_FALSE;
- }
-
- client->before_state = client->current_state;
- client->current_state = TTS_STATE_READY;
-
- if (0 != tts_core_notify_state_changed(client, client->before_state, client->current_state)) {
- return EINA_FALSE;
- }
-
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
-
- return EINA_FALSE;
-}
-
-int __tts_cb_hello(int uid, int ret, int credential_needed)
-{
- tts_client_s* client = tts_client_get_by_uid(uid);
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%d)", uid);
- return TTS_ERROR_OPERATION_FAILED;
- }
-
- if (client->hello_timer) {
- ecore_timer_del(client->hello_timer);
- client->hello_timer = NULL;
- }
-
- if (TTS_STATE_READY == client->current_state) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY");
- return TTS_ERROR_NONE;
- }
-
- if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
-
- client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
- client->utt_id = -1;
-
- if (NULL != g_notify_error_timer) {
- ecore_timer_del(g_notify_error_timer);
- g_notify_error_timer = NULL;
- }
- g_notify_error_timer = ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
-
- return TTS_ERROR_OPERATION_FAILED;
-
- } else if (TTS_ERROR_PERMISSION_DENIED == ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
-
- client->reason = TTS_ERROR_PERMISSION_DENIED;
- client->utt_id = -1;
-
- if (NULL != g_notify_error_timer) {
- ecore_timer_del(g_notify_error_timer);
- g_notify_error_timer = NULL;
- }
- g_notify_error_timer = ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
-
- return TTS_ERROR_PERMISSION_DENIED;
-
- } else if (TTS_ERROR_NONE != ret) {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
- return TTS_ERROR_OPERATION_FAILED;
-
- } else {
- /* success to connect tts-daemon */
- if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
- client->credential_needed = credential_needed;
- SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
- }
- }
-
- client->before_state = client->current_state;
- client->current_state = TTS_STATE_READY;
-
- if (NULL != g_check_state_timer) {
- ecore_timer_del(g_check_state_timer);
- g_check_state_timer = NULL;
- }
- g_check_state_timer = ecore_timer_add(0.0, __tts_notify_state_changed, client->tts);
-
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
- return TTS_ERROR_NONE;
-}
-
-static bool __is_engine_installed(const char* appid)
-{
- app_info_h app_info = NULL;
- int ret = app_manager_get_app_info(appid, &app_info);
- if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no tts engine (%s). ret(%d)", appid, ret);
- return false;
- } else {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
- }
-
- ret = app_info_destroy(app_info);
- if (APP_MANAGER_ERROR_NONE != ret)
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy app_info. ret(%d)", ret);
-
- return true;
-}
-
-static bool __is_engine_launched(const char* appid)
-{
- int ret = -1;
- bool is_installed = false;
- bool is_running = false;
- is_installed = __is_engine_installed(appid);
-
- if (false == is_installed) {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] tts engine(%s) is not installed", appid);
- return false;
- } else {
- ret = app_manager_is_running(appid, &is_running);
- if (APP_MANAGER_ERROR_NONE != ret) {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is installed(%d)", is_installed);
- return false;
- } else {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is%s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
- }
-
- return is_running;
- }
-}
-
-static Eina_Bool __send_hello(void *data)
-{
- tts_h tts = (tts_h)data;
- tts_client_s* client = tts_client_get(tts);
-
- /* check handle */
- if (NULL == client) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- g_prepare_timer = NULL;
- return EINA_FALSE;
- }
-
- /* check state */
- if (client->current_state == TTS_STATE_READY) {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
- SLOG(LOG_ERROR, TAG_TTSC, "@@@");
- client->hello_timer = NULL;
- g_prepare_timer = NULL;
- return EINA_FALSE;
- }
-
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
-
- bool is_launched = __is_engine_launched(g_engine_appid);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
-
- if (false == is_launched) {
- /* If engine is NOT launched, check whether engine is updating or not */
- if (g_engine_update_status) {
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
- if (NULL == client->thread) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
- client->thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, tts);
- }
- client->hello_timer = NULL;
- g_prepare_timer = NULL;
- return EINA_FALSE;
- }
- }
-
- /* Send hello */
- int ret = tts_dbus_request_hello(client->uid);
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
- } else {
- SLOG(LOG_ERROR, TAG_TTSC, "@@@ Send Hello");
- }
-
- g_retry_cnt++;
- if (TTS_HELLO_RETRY_COUNT == g_retry_cnt) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Stop to send hello, retry count reaches the limit");
- g_retry_cnt = 0;
- client->hello_timer = NULL;
- g_prepare_timer = NULL;
-
- is_launched = __is_engine_launched(g_engine_appid);
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
-
- return EINA_FALSE;
- }
-
- if (!client->hello_timer) {
- SLOG(LOG_ERROR, TAG_TTSC, "@@@ Call checking Hello timer callback");
- client->hello_timer = ecore_timer_add(0.5, __send_hello, tts);
- g_prepare_timer = NULL;
-
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
int tts_prepare(tts_h tts)
{
if (0 != __tts_get_feature_enabled()) {
return TTS_ERROR_NOT_SUPPORTED;
}
- SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
-
tts_client_s* client = tts_client_get(tts);
/* check handle */
if (NULL == client) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_INVALID_PARAMETER;
}
return TTS_ERROR_INVALID_STATE;
}
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
-
- if (NULL == client->hello_timer) {
- SLOG(LOG_ERROR, TAG_TTSC, "@@@ Call checking Hello timer callback");
- g_retry_cnt = 0;
- ecore_thread_main_loop_begin();
- if (NULL != g_prepare_timer) {
- ecore_timer_del(g_prepare_timer);
- g_prepare_timer = NULL;
- }
- g_prepare_timer = ecore_timer_add(0.0, __send_hello, (void*)tts);
- ecore_thread_main_loop_end();
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
+ int ret = tts_core_prepare(client);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_prepare failed. (%s)", __tts_get_error_code(ret));
+ return ret;
}
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NOT_SUPPORTED;
}
- SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
-
tts_client_s* client = tts_client_get(tts);
/* check handle */
if (NULL == client) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_INVALID_PARAMETER;
}
return TTS_ERROR_INVALID_STATE;
}
- int cnt = 0;
- while (EINA_TRUE == __tts_connect_daemon((void*)tts) && TTS_CONNECTION_RETRY_COUNT > cnt) {
- cnt++;
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS synchronously");
+ int ret = tts_core_prepare_sync(client);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_prepare_sync failed. (%s)", __tts_get_error_code(ret));
+ return ret;
}
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
- if (TTS_CONNECTION_RETRY_COUNT == cnt) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
- return TTS_ERROR_OPERATION_FAILED;
- }
-
return TTS_ERROR_NONE;
}
//LCOV_EXCL_STOP
return TTS_ERROR_NOT_SUPPORTED;
}
- SLOG(LOG_INFO, TAG_TTSC, "@@@ Unprepare TTS");
-
tts_client_s* client = tts_client_get(tts);
/* check handle */
return TTS_ERROR_INVALID_STATE;
}
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
-
- if (client->hello_timer) {
- ecore_timer_del(client->hello_timer);
- client->hello_timer = NULL;
- }
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Unprepare TTS");
int ret = -1;
- int count = 0;
-
ret = __tts_recheck_screen_reader();
if (0 != ret) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader(%d)", ret);
}
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] g_screen_reader(%s), client->mode(%d)", (true == g_screen_reader) ? "True" : "False", client->mode);
-
- bool is_prepared = false;
- if (!(false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode)) {
- do {
- ret = tts_dbus_request_finalize(client->uid);
- if (0 != ret) {
- //LCOV_EXCL_START
- if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
- client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
- is_prepared = true;
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
- }
- } else if (TTS_ERROR_TIMED_OUT != ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
- break;
- } else {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry finalize : %s", __tts_get_error_code(ret));
- usleep(10000);
- count++;
- if (TTS_RETRY_COUNT == count) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
- break;
- }
- }
- //LCOV_EXCL_STOP
- }
- } while (0 != ret);
- } else {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : g_sr(%d) mode(%d)", g_screen_reader, client->mode);
- ret = tts_dbus_remove_match(client->mode);
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret));
- }
+ ret = tts_core_unprepare(tts_client_get(tts), g_screen_reader);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_unprepare is failed(%s)", __tts_get_error_code(ret));
+ return ret;
}
- client->before_state = client->current_state;
- client->current_state = TTS_STATE_CREATED;
-
- tts_core_notify_state_changed(client, client->before_state, client->current_state);
-
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NONE;
}
-bool __tts_supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
+static bool __tts_supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
{
- tts_h tts = (tts_h)user_data;
+ tts_client_s* client = (tts_client_s*)user_data;
/* call callback function */
- tts_core_notify_supported_voice(tts_client_get(tts), language, type);
+ // TODO: pass return value of callback
+ tts_core_notify_supported_voice(client, language, type);
return false;
}
return TTS_ERROR_NOT_SUPPORTED;
}
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Foreach supported voices");
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Foreach supported voices");
if (NULL == tts || NULL == callback) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_INVALID_PARAMETER;
}
/* check handle */
if (NULL == client) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
- SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_INVALID_PARAMETER;
}
client->supported_voice_cb = callback;
client->supported_voice_user_data = user_data;
-
- ret = tts_config_mgr_get_voice_list(current_engine, __tts_supported_voice_cb, client->tts);
+ ret = tts_config_mgr_get_voice_list(current_engine, __tts_supported_voice_cb, client);
if (NULL != current_engine) {
free(current_engine);
return TTS_ERROR_NONE;
}
-int __tts_recheck_screen_reader()
-{
- SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Check screen reader again");
-
- int ret = -1;
- int screen_reader = 0;
-
- ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
- return TTS_ERROR_INVALID_STATE;
- } else {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
- g_screen_reader = (bool)screen_reader;
- }
-
- return TTS_ERROR_NONE;
-}
-
int tts_add_text(tts_h tts, const char* text, const char* language, int voice_type, int speed, int* utt_id)
{
SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Add text: text(%s), language(%s), type(%d)", (NULL == text) ? "NULL" : text, (NULL == language) ? "NULL" : language, voice_type);
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
//LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
client->current_state = TTS_STATE_CREATED;
- if (0 == tts_prepare_sync(tts)) {
+ if (0 == tts_core_prepare_sync(client)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
}
* limitations under the License.
*/
+#include <string.h>
+
+#include <app_manager.h>
#include <dlog.h>
+#include <package-manager.h>
+#include "tts_internal.h"
+#include "tts_dbus.h"
#include "tts_defs.h"
#include "tts_core.h"
/* Static variables */
+static char* g_engine_name = NULL;
+static int g_engine_update_status = 0;
+
+static pkgmgr_client* g_pkgmgr = NULL;
+
/* Static functions */
static const char* __tts_get_error_code(tts_error_e err)
return NULL;
}
+static char* __get_engine_appid(int mode) {
+ char* appid = NULL;
+ appid = (char*)calloc(sizeof(char), 256);
+
+ if (NULL == appid || NULL == g_engine_name) {
+ return NULL;
+ }
+
+ memset(appid, '\0', 256);
+ if (TTS_MODE_DEFAULT == mode) {
+ snprintf(appid, 256, "%s", g_engine_name);
+ } else if (TTS_MODE_NOTIFICATION == mode) {
+ snprintf(appid, 256, "%s-noti", g_engine_name);
+ } else if (TTS_MODE_SCREEN_READER == mode) {
+ snprintf(appid, 256, "%s-sr", g_engine_name);
+ } else if (TTS_MODE_INTERRUPT == mode) {
+ snprintf(appid, 256, "%s-interrupt", g_engine_name);
+ }
+ return appid;
+}
+
+static Eina_Bool __notify_error_timer_cb(void *data)
+{
+ tts_client_s* client = (tts_client_s*)data;
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ } else {
+ tts_core_notify_error(client, client->utt_id, client->reason);
+ }
+
+ client->notify_error_timer = NULL;
+
+ return EINA_FALSE;
+}
+
+static Eina_Bool __notify_state_timer_cb(void *data)
+{
+ tts_client_s* client = (tts_client_s*)data;
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ } else {
+ tts_core_notify_state_changed(client, client->before_state, client->current_state);
+ }
+
+ client->notify_state_timer = NULL;
+ return EINA_FALSE;
+}
+
+static bool __is_engine_installed(const char* appid)
+{
+ app_info_h app_info = NULL;
+ int ret = app_manager_get_app_info(appid, &app_info);
+ if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no tts engine (%s). ret(%d)", appid, ret);
+ return false;
+ } else {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
+ }
+
+ ret = app_info_destroy(app_info);
+ if (APP_MANAGER_ERROR_NONE != ret)
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy app_info. ret(%d)", ret);
+
+ return true;
+}
+
+static bool __is_engine_launched(int mode)
+{
+ int ret = -1;
+ bool is_installed = false;
+ bool is_running = false;
+
+ char* appid = __get_engine_appid(mode);
+ if (NULL == appid) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
+ return false;
+ }
+
+ is_installed = __is_engine_installed(appid);
+ if (false == is_installed) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] tts engine(%s) is not installed", appid);
+ free(appid);
+ return false;
+ }
+
+ ret = app_manager_is_running(appid, &is_running);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret);
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is installed(%d)", is_installed);
+ free(appid);
+ return false;
+ } else {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
+ }
+
+ free(appid);
+ return is_running;
+}
+
+static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
+
+ tts_client_s* client = (tts_client_s*)data;
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return;
+ }
+
+ int cnt = 0;
+ while (!g_engine_update_status && cnt < 20) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
+ /* Checking handle which can be destroyed on other thread */
+ if (false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
+ return;
+ }
+
+ usleep(50000);
+ cnt++;
+
+ /* Checking thread is canceled or not */
+ if (ecore_thread_check(client->thread)) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
+ return;
+ }
+ }
+
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
+
+ while (g_engine_update_status && (NULL != g_pkgmgr)) {
+ /* Checking handle which can be destroyed on other thread */
+ if (false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
+ return;
+ }
+
+ usleep(200000);
+
+ /* Checking thread is canceled or not */
+ if (ecore_thread_check(client->thread)) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
+ return;
+ }
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
+
+ if (0 != tts_core_prepare(client)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
+ }
+
+ return;
+}
+
+static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
+
+ tts_client_s* client = (tts_client_s*)data;
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return;
+ }
+
+ client->thread = NULL;
+}
+
+static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
+
+ tts_client_s* client = (tts_client_s*)data;
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return;
+ }
+
+ client->thread = NULL;
+}
+
+static int __send_hello_msg(tts_client_s* client)
+{
+ if (NULL == client) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check state */
+ if (client->current_state == TTS_STATE_READY) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
+ return TTS_ERROR_INVALID_STATE;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", client->tts, client, client->uid);
+
+ /* check service engine status */
+ bool is_launched = __is_engine_launched(client->mode);
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
+ if (false == is_launched) {
+ /* If engine is NOT launched, check whether engine is updating or not */
+ if (g_engine_update_status) {
+ /* suyeon wait engine update */
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] cannot prepare due to engine update");
+ if (NULL == client->thread) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
+ client->thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, client);
+ }
+ return TTS_ERROR_INVALID_STATE;
+ }
+ }
+
+ /* Send hello */
+ int ret = tts_dbus_request_hello(client->uid);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
+ } else {
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
+ }
+
+ return TTS_ERROR_NONE;
+}
+
+static Eina_Bool __prepare_cb(void *data)
+{
+ tts_client_s* client = (tts_client_s*)data;
+
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ client->hello_timer = NULL;
+ return EINA_FALSE;
+ }
+
+ /* check state */
+ int ret = __send_hello_msg(client);
+ if (ret != TTS_ERROR_NONE) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to send hello message"); //LCOV_EXCL_LINE
+ client->hello_timer = NULL;
+ return EINA_FALSE;
+ }
+
+ client->prepare_count++;
+ if (TTS_HELLO_RETRY_COUNT == client->prepare_count) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Stop to prepare, retry count reaches the limit");
+
+ bool is_launched = __is_engine_launched(client->mode);
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
+
+ client->hello_timer = NULL;
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool __prepare_first_cb(void *data)
+{
+ /* send first hello message */
+ tts_client_s* client = (tts_client_s*)data;
+
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ client->hello_timer = NULL;
+ return EINA_FALSE;
+ }
+
+ int ret = __send_hello_msg(client);
+ if (ret != TTS_ERROR_NONE) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to sent hello message"); //LCOV_EXCL_LINE
+ client->hello_timer = NULL;
+ } else {
+ /* Set retry timer callback */
+ client->prepare_count = 0;
+ client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
+ }
+
+ return EINA_FALSE;
+}
+
+static Eina_Bool __prepare_sync_cb(tts_client_s* client)
+{
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ client->hello_timer = NULL;
+ return EINA_FALSE;
+ }
+
+ // TODO: make function duplicated block
+ bool is_launched = __is_engine_launched(client->mode);
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
+
+ if (false == is_launched) {
+ /* check whether engine is updating or not */
+ if (g_engine_update_status) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
+ if (NULL == client->thread) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
+ client->thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, client);
+ }
+ return EINA_FALSE;
+ }
+ }
+ // TODO: make function duplicated block
+
+ /* Send hello */
+ if (0 != tts_dbus_request_hello_sync(client->uid)) {
+ return EINA_TRUE;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
+
+ // TODO: make function duplicated block
+ /* do request initialize */
+ int ret = -1;
+ bool credential_needed = false;
+
+ ret = tts_dbus_request_initialize(client->uid, &credential_needed);
+
+ if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
+
+ client->reason = ret;
+ client->utt_id = -1;
+
+ if (NULL != client->notify_error_timer) {
+ ecore_timer_del(client->notify_error_timer);
+ }
+ client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)client);
+
+ return EINA_FALSE;
+ } else if (TTS_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
+ return EINA_TRUE;
+ } else {
+ /* success to connect tts-daemon */
+ client->credential_needed = credential_needed;
+ SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
+ }
+ // TODO: make function duplicated block
+
+ /* check handle */
+ if (false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
+ return EINA_FALSE;
+ }
+
+ client->before_state = client->current_state;
+ client->current_state = TTS_STATE_READY;
+
+ if (0 != tts_core_notify_state_changed(client, client->before_state, client->current_state)) {
+ return EINA_FALSE;
+ }
+
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+
+ return EINA_FALSE;
+}
+
+
/* Public functions */
int tts_core_notify_state_changed(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
{
return TTS_ERROR_NONE;
}
+
+int tts_core_receive_hello(int uid, int ret, int credential_needed)
+{
+ tts_client_s* client = tts_client_get_by_uid(uid);
+ if (NULL == client) {
+ SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%d)", uid);
+ return TTS_ERROR_OPERATION_FAILED;
+ }
+
+ if (client->hello_timer) {
+ ecore_timer_del(client->hello_timer);
+ client->hello_timer = NULL;
+ }
+
+ if (TTS_STATE_READY == client->current_state) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY");
+ return TTS_ERROR_NONE;
+ }
+
+ if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
+
+ client->reason = ret;
+ client->utt_id = -1;
+
+ if (NULL != client->notify_error_timer) {
+ ecore_timer_del(client->notify_error_timer);
+ }
+ client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)client);
+
+ return TTS_ERROR_OPERATION_FAILED;
+ } else if (TTS_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
+ return TTS_ERROR_OPERATION_FAILED;
+ } else {
+ /* success to connect tts-daemon */
+ if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
+ client->credential_needed = credential_needed;
+ SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%d)", credential_needed);
+ }
+ }
+
+ client->before_state = client->current_state;
+ client->current_state = TTS_STATE_READY;
+
+ if (NULL != client->notify_state_timer) {
+ ecore_timer_del(client->notify_state_timer);
+ }
+ client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, client);
+
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+ return TTS_ERROR_NONE;
+}
+
+int tts_core_update_engine_name()
+{
+ if (g_engine_name) {
+ free(g_engine_name);
+ g_engine_name = NULL;
+ }
+
+ g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
+ if (NULL == g_engine_name) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
+ return TTS_ERROR_OPERATION_FAILED;
+ }
+
+ SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
+ return TTS_ERROR_NONE;
+}
+
+const char* tts_core_get_engine_name()
+{
+ return g_engine_name;
+}
+
+int tts_core_prepare(tts_client_s* client)
+{
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", client->tts, client, client->uid);
+ if (NULL == client->hello_timer) {
+ SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
+
+ ecore_thread_main_loop_begin();
+ client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)client);
+ ecore_thread_main_loop_end();
+ } else {
+ LOGD("Client is already trying to prepare");
+ }
+
+ return TTS_ERROR_NONE;
+}
+
+int tts_core_prepare_sync(tts_client_s* client)
+{
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", client->tts, client, client->uid);
+ int cnt = 0;
+ while (EINA_TRUE == __prepare_sync_cb(client) && TTS_CONNECTION_RETRY_COUNT > cnt) {
+ cnt++;
+ }
+
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+
+ if (TTS_CONNECTION_RETRY_COUNT == cnt) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
+ return TTS_ERROR_OPERATION_FAILED;
+ }
+
+ return TTS_ERROR_NONE;
+}
+
+int tts_core_unprepare(tts_client_s* client, bool is_screen_reader_on)
+{
+ /* check handle */
+ if (NULL == client || false == tts_client_is_valid(client->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", client->tts, client, client->uid);
+ if (client->hello_timer) {
+ ecore_timer_del(client->hello_timer);
+ client->hello_timer = NULL;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] screen_reader(%s), client->mode(%d)", (true == is_screen_reader_on) ? "True" : "False", client->mode);
+
+ int ret = -1;
+ int count = 0;
+ if (false == is_screen_reader_on && TTS_MODE_SCREEN_READER == client->mode) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : is_screen_reader(%d) mode(%d)", is_screen_reader_on, client->mode);
+
+ ret = tts_dbus_remove_match(client->mode);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret));
+ }
+ } else {
+ bool is_prepared = false;
+
+ do {
+ ret = tts_dbus_request_finalize(client->uid);
+ if (0 != ret) {
+ //LCOV_EXCL_START
+ if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
+ if (0 == tts_core_prepare_sync(client)) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
+ is_prepared = true;
+ }
+ } else if (TTS_ERROR_TIMED_OUT != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
+ break;
+ } else {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry finalize : %s", __tts_get_error_code(ret));
+ usleep(10000);
+ count++;
+ if (TTS_RETRY_COUNT == count) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
+ break;
+ }
+ }
+ //LCOV_EXCL_STOP
+ }
+ } while (0 != ret);
+ }
+
+ client->before_state = client->current_state;
+ client->current_state = TTS_STATE_CREATED;
+
+ tts_core_notify_state_changed(client, client->before_state, client->current_state);
+
+ return TTS_ERROR_NONE;
+}