static int g_speed = -1;
-/* for checking engine update */
-static pkgmgr_client* g_pkgmgr = NULL;
-static char* g_pkgmgr_status = NULL;
-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 int __tts_get_feature_enabled()
{
return 0;
}
+// TODO: move into tts_core to make common function
static const char* __tts_get_error_code(tts_error_e err)
{
switch (err) {
return NULL;
}
+// TODO: move into tts_core to make common function
static int __tts_convert_config_error_code(tts_config_error_e code)
{
if (code == TTS_CONFIG_ERROR_NONE) return TTS_ERROR_NONE;
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
}
-static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *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);
-
- 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(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 (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;
- }
- }
- } 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;
-
- free(g_pkgmgr_status);
- g_pkgmgr_status = NULL;
- }
- }
- }
- }
- }
-
- return 0;
-}
-
-static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
-{
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] create pkgmgr thread");
-
- g_is_finished_pkgmgr_thread = false;
-
- 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] client is null");
- g_is_finished_pkgmgr_thread = true;
- return ;
- }
-
- pthread_mutex_lock(&g_pkgmgr_mutex);
-
- while (!g_pkgmgr) {
- g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
- if (NULL == g_pkgmgr) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
- } else {
- int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
- if (0 == ret) {
- if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
- pkgmgr_client_free(g_pkgmgr);
- g_pkgmgr = NULL;
- usleep(10000);
- continue;
- } else {
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
- }
- } else {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
- pkgmgr_client_free(g_pkgmgr);
- g_pkgmgr = NULL;
- usleep(10000);
- continue;
- }
- }
- usleep(10000);
-
- /* Checking the thread is canceled or not */
- if (ecore_thread_check(g_pkgmgr_thread)) {
- SLOG(LOG_WARN, TAG_TTSC, "[WARNING] g_pkgmgr_thread is canceled. Exit");
- break;
- }
-
- /* Checking handle which can be destroyed on other thread */
- if (false == tts_client_is_valid(tts)) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
- break;
- }
- }
-
- pthread_mutex_unlock(&g_pkgmgr_mutex);
- g_is_finished_pkgmgr_thread = true;
- SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Finish pkgmgr_thread. func_end will be invoked in main thread.");
-
- return ;
-}
-
-static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
-{
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
- g_pkgmgr_thread = NULL;
-}
-
-static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
-{
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
- g_pkgmgr_thread = NULL;
-}
-
-static void __pkgmgr_thread(void* data)
-{
- SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
-
- tts_h tts = (tts_h)data;
- if (NULL == tts) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
- return ;
- }
-
- if (NULL == g_pkgmgr_thread) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
- g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, __cancel_pkgmgr_thread, tts);
- }
- return ;
-}
-
-static void __tts_config_engine_changed_cb(keynode_t* key, void* data)
-{
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
-
- if (0 != tts_core_update_engine_name()) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
- return;
- }
-
- return;
-}
-
int tts_create(tts_h* tts)
{
if (0 != __tts_get_feature_enabled()) {
return TTS_ERROR_INVALID_PARAMETER;
}
+ bool is_first_client = false;
if (0 == tts_client_get_size()) {
- if (0 != tts_dbus_open_connection()) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
- return TTS_ERROR_OPERATION_FAILED;
- }
+ is_first_client = true;
}
if (0 != tts_client_new(tts)) {
return __tts_convert_config_error_code(ret);
}
- //TODO: move to tts_core
- ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, *tts);
-
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] call ecore thread for creating pkgmgr thread");
+ if (is_first_client) {
+ // These function would be called only when first client is created.
+ if (0 != tts_dbus_open_connection()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
+ tts_client_destroy(*tts);
+ return TTS_ERROR_OPERATION_FAILED;
+ }
- 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;
+ if (0 != tts_core_initialize()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize core");
+ tts_client_destroy(*tts);
+ 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, "@@@");
-
return TTS_ERROR_NONE;
}
return TTS_ERROR_OPERATION_FAILED;
}
- /* Unregister vconfkey callback */
- vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __tts_config_engine_changed_cb);
-
tts_config_mgr_finalize(client->uid);
if (client->hello_timer) {
__tts_unset_all_callbacks(tts);
/* Cancel and Check threads */
- if (NULL != g_pkgmgr_thread && false == ecore_thread_check(g_pkgmgr_thread) && false == g_is_finished_pkgmgr_thread) {
- SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr thread is not finished. Cancel pkgmgr thread");
- ecore_thread_cancel(g_pkgmgr_thread);
- }
if (NULL != client->thread && false == ecore_thread_check(client->thread)) {
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel client thread");
ecore_thread_cancel(client->thread);
if (0 != tts_dbus_close_connection()) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
}
- pthread_mutex_lock(&g_pkgmgr_mutex);
- if (g_pkgmgr) {
- pkgmgr_client_remove_listen_status(g_pkgmgr);
- pkgmgr_client_free(g_pkgmgr);
- g_pkgmgr = NULL;
- }
- if (NULL != g_pkgmgr_status) {
- free(g_pkgmgr_status);
- g_pkgmgr_status = NULL;
+
+ if (0 != tts_core_deinitialize()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to deinitialize core");
}
- pthread_mutex_unlock(&g_pkgmgr_mutex);
} else {
SLOG(LOG_ERROR, TAG_TTSC, "[INFO] num_of_client(%d)", num_of_client);
}
g_language = NULL;
}
-
- tts = NULL;
-
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NONE;
#include "tts_core.h"
/* Static variables */
+static volatile bool g_is_thread_canceled = false;
+
static char* g_engine_name = NULL;
static int g_engine_update_status = 0;
+static char* g_pkgmgr_status = NULL;
static pkgmgr_client* g_pkgmgr = NULL;
+static Ecore_Thread* g_pkgmgr_thread = NULL;
+static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Static functions */
return appid;
}
+static int __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;
+}
+
static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
{
if (NULL != client->error_cb) {
return is_running;
}
+static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *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) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
+ return 0;
+ }
+
+ if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
+ SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
+ return 0;
+ }
+
+ if (NULL == key) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
+ return 0;
+ }
+
+ if (0 == strncmp(key, "start", strlen(key))) {
+ 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 ((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;
+
+ free(g_pkgmgr_status);
+ g_pkgmgr_status = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
+
+ pthread_mutex_lock(&g_pkgmgr_mutex);
+ while (NULL == g_pkgmgr) {
+ /* Checking the thread is canceled or not */
+ if (g_is_thread_canceled) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] g_pkgmgr_thread is canceled. Exit");
+ break;
+ }
+
+ /* Checking handle which can be destroyed on other thread */
+ if (0 == tts_client_get_size()) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] All client is already destroyed");
+ break;
+ }
+
+ g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
+ if (NULL == g_pkgmgr) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
+ } else {
+ int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
+ if (0 == ret) {
+ if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ } else {
+ SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
+ break;
+ }
+ } else {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ }
+ }
+
+ usleep(10000);
+ }
+ pthread_mutex_unlock(&g_pkgmgr_mutex);
+
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
+}
+
+static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
+ g_is_thread_canceled = false;
+ g_pkgmgr_thread = NULL;
+}
+
+static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
+ g_is_thread_canceled = false;
+ g_pkgmgr_thread = NULL;
+}
+
+static void __pkgmgr_thread(void* data)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
+ if (NULL == g_pkgmgr_thread) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
+ g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, __cancel_pkgmgr_thread, NULL);
+ }
+
+ return ;
+}
+
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);
return EINA_FALSE;
}
+static void __engine_changed_cb(keynode_t* key, void* data)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
+ if (0 != __update_engine_name()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
+ }
+
+ return;
+}
+
/* Public functions */
+int tts_core_initialize()
+{
+ ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
+
+ if (0 != __update_engine_name()) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
+ }
+
+ /* Register vconfkey callback to detect engine change */
+ vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
+
+ return TTS_ERROR_NONE;
+}
+
+int tts_core_deinitialize()
+{
+ if (NULL != g_pkgmgr_thread) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
+ g_is_thread_canceled = true;
+ }
+
+ pthread_mutex_lock(&g_pkgmgr_mutex);
+ if (NULL != g_pkgmgr) {
+ pkgmgr_client_remove_listen_status(g_pkgmgr);
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ }
+
+ if (NULL != g_pkgmgr_status) {
+ free(g_pkgmgr_status);
+ g_pkgmgr_status = NULL;
+ }
+ pthread_mutex_unlock(&g_pkgmgr_mutex);
+
+ /* Unregister vconfkey callback */
+ vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
+
+ return TTS_ERROR_NONE;
+}
+
int tts_core_notify_state_changed(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
{
/* check handle */
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;