X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=common%2Ftts_config_mgr.c;h=1522950376d9ff5fce2c289e2c3d8d2d6079b4e4;hb=refs%2Fchanges%2F51%2F167951%2F1;hp=c323f4f439e6ff5743c309a14e514e5697ebfeb1;hpb=f12630d43a0365d8baa6f46095824b3a95d95eae;p=platform%2Fcore%2Fuifw%2Ftts.git diff --git a/common/tts_config_mgr.c b/common/tts_config_mgr.c old mode 100755 new mode 100644 index c323f4f..1522950 --- a/common/tts_config_mgr.c +++ b/common/tts_config_mgr.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved +* Copyright (c) 2011-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 @@ -20,6 +20,7 @@ #include #include #include +#include #include "tts_config_mgr.h" #include "tts_config_parser.h" @@ -41,18 +42,27 @@ static GSList* g_engine_list = NULL; static GSList* g_config_client_list = NULL; -static tts_config_s* g_config_info; +static tts_config_s* g_config_info = NULL; +extern char g_engine_id[128]; +extern char g_setting[128]; +extern char g_language[128]; static Ecore_Fd_Handler* g_config_fd_handler_noti = NULL; static int g_config_fd_noti; static int g_config_wd_noti; /* For engine directory monitoring */ -static Ecore_Fd_Handler* g_dir_fd_handler = NULL; -static int g_dir_fd; -static int g_dir_wd; +typedef struct { + Ecore_Fd_Handler* dir_fd_handler; + int dir_fd; + int dir_wd; +} tts_engine_inotify_s; + +static GList* g_ino_list = NULL; int __tts_config_mgr_print_engine_info(); +static int __tts_config_mgr_register_engine_config_updated_event(const char* path); +static int __tts_config_mgr_unregister_engine_config_updated_event(); int __tts_config_mgr_check_engine_is_valid(const char* engine_id) { @@ -80,7 +90,7 @@ int __tts_config_mgr_check_engine_is_valid(const char* engine_id) return -1; } - if (0 == strcmp(engine_id, engine_info->uuid)) { + if (NULL != engine_info->uuid && 0 == strcmp(engine_id, engine_info->uuid)) { SLOG(LOG_DEBUG, tts_tag(), "Default engine is valid : %s", engine_id); return 0; } @@ -90,17 +100,27 @@ int __tts_config_mgr_check_engine_is_valid(const char* engine_id) /* Change default engine */ iter = g_slist_nth(g_engine_list, 0); - engine_info = iter->data; + if (NULL == iter) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] No engine in list"); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + engine_info = iter->data; if (NULL == g_config_info) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine info in list"); return TTS_CONFIG_ERROR_OPERATION_FAILED; } - if (NULL != g_config_info->engine_id) free(g_config_info->engine_id); - if (NULL != g_config_info->setting) free(g_config_info->setting); - - g_config_info->engine_id = strdup(engine_info->uuid); - g_config_info->setting = strdup(engine_info->setting); + if (NULL != engine_info->uuid) { + memset(g_engine_id, '\0', sizeof(g_engine_id)); + g_config_info->engine_id = g_engine_id; + strncpy(g_config_info->engine_id, engine_info->uuid, sizeof(g_engine_id) - 1); + } + if (NULL != engine_info->setting) { + memset(g_setting, '\0', sizeof(g_setting)); + g_config_info->setting = g_setting; + strncpy(g_config_info->setting, engine_info->setting, sizeof(g_setting) - 1); + } SLOG(LOG_DEBUG, tts_tag(), "Default engine is changed : %s", g_config_info->engine_id); @@ -117,14 +137,16 @@ int __tts_config_mgr_check_engine_is_valid(const char* engine_id) voice = iter_voice->data; if (NULL != voice) { - if (NULL != voice->language && NULL != g_config_info->language) { + if (NULL != voice->language) { if (0 == strcmp(voice->language, g_config_info->language)) { if (voice->type == g_config_info->type) { /* language is valid */ is_valid_voice = true; - free(g_config_info->language); - g_config_info->language = strdup(voice->language); + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, voice->language, sizeof(g_language) - 1); + g_config_info->type = voice->type; SLOG(LOG_DEBUG, tts_tag(), "Default voice is changed : lang(%s) type(%d)", voice->language, voice->type); @@ -139,16 +161,24 @@ int __tts_config_mgr_check_engine_is_valid(const char* engine_id) if (false == is_valid_voice) { /* Select first voice as default */ - if (NULL != g_config_info->language) { - free(g_config_info->language); + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; - iter_voice = g_slist_nth(engine_info->voices, 0); - voice = iter_voice->data; + iter_voice = g_slist_nth(engine_info->voices, 0); + if (NULL == iter_voice) { + SLOG(LOG_ERROR, tts_tag(), "Fail to get voice list"); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + voice = iter_voice->data; - g_config_info->language = strdup(voice->language); - g_config_info->type = voice->type; - SLOG(LOG_DEBUG, tts_tag(), "Default voice is changed : lang(%s) type(%d)", voice->language, voice->type); + if (NULL == voice || NULL == voice->language) { + SLOG(LOG_ERROR, tts_tag(), "Fail to get voice info from list"); + return TTS_CONFIG_ERROR_OPERATION_FAILED; } + strncpy(g_config_info->language, voice->language, sizeof(g_language) - 1); + + g_config_info->type = voice->type; + SLOG(LOG_DEBUG, tts_tag(), "Default voice is changed : lang(%s) type(%d)", voice->language, voice->type); } if (0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting, @@ -300,7 +330,7 @@ int __tts_config_mgr_select_lang(const char* engine_id, char** language, int* ty Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler) { - SLOG(LOG_DEBUG, tts_tag(), "===== Config changed callback event"); + SLOG(LOG_DEBUG, tts_tag(), "@@@ Config changed callback event"); int length; struct inotify_event event; @@ -309,8 +339,7 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl length = read(g_config_fd_noti, &event, sizeof(struct inotify_event)); if (0 > length) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty Inotify event"); - SLOG(LOG_DEBUG, tts_tag(), "====="); - SLOG(LOG_DEBUG, tts_tag(), " "); + SLOG(LOG_DEBUG, tts_tag(), "@@@"); return ECORE_CALLBACK_DONE; } @@ -333,16 +362,14 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl /* engine changed */ if (NULL != engine || NULL != setting) { if (NULL != engine) { - if (NULL != g_config_info->engine_id) - free(g_config_info->engine_id); - - g_config_info->engine_id = strdup(engine); + memset(g_engine_id, '\0', sizeof(g_engine_id)); + g_config_info->engine_id = g_engine_id; + strncpy(g_config_info->engine_id, engine, sizeof(g_engine_id) - 1); } if (NULL != setting) { - if (NULL != g_config_info->setting) - free(g_config_info->setting); - - g_config_info->setting = strdup(setting); + memset(g_setting, '\0', sizeof(g_setting)); + g_config_info->setting = g_setting; + strncpy(g_config_info->setting, setting, sizeof(g_setting) - 1); } SECURE_SLOG(LOG_DEBUG, tts_tag(), "Engine change(%s)", g_config_info->engine_id); @@ -358,7 +385,7 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl SECURE_SLOG(LOG_DEBUG, tts_tag(), "Engine changed callback : uid(%d)", temp_client->uid); temp_client->engine_cb(g_config_info->engine_id, g_config_info->setting, g_config_info->language, g_config_info->type, - g_config_info->auto_voice, temp_client->user_data); + g_config_info->auto_voice, g_config_info->credential, temp_client->user_data); } } @@ -378,10 +405,9 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl before_type = g_config_info->type; if (NULL != lang) { - if (NULL != g_config_info->language) - free(g_config_info->language); - - g_config_info->language = strdup(lang); + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, lang, sizeof(g_language) - 1); } if (-1 != voice_type) { g_config_info->type = voice_type; @@ -409,6 +435,7 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl if (NULL != before_lang) { free(before_lang); + before_lang = NULL; } } @@ -456,15 +483,29 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl } } - if (NULL != engine) free(engine); - if (NULL != setting) free(setting); - if (NULL != lang) free(lang); + if (NULL != engine) { + free(engine); + engine = NULL; + } + if (NULL != setting) { + free(setting); + setting = NULL; + } + if (NULL != lang) { + free(lang); + lang = NULL; + } + } else if (IN_DELETE_SELF == event.mask) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] IN_DELETE_SELF event"); + + tts_parser_unload_config(g_config_info); + tts_parser_reset(); + tts_parser_load_config(&g_config_info); } else { - SLOG(LOG_ERROR, tts_tag(), "[ERROR] Undefined event"); + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Undefined event (0x%x)", event.mask); } - SLOG(LOG_DEBUG, tts_tag(), "====="); - SLOG(LOG_DEBUG, tts_tag(), " "); + SLOG(LOG_DEBUG, tts_tag(), "@@@"); return ECORE_CALLBACK_PASS_ON; } @@ -482,7 +523,7 @@ int __tts_config_mgr_register_config_event() } g_config_fd_noti = fd; - wd = inotify_add_watch(fd, TTS_CONFIG, IN_CLOSE_WRITE); + wd = inotify_add_watch(fd, TTS_CONFIG, IN_CLOSE_WRITE|IN_DELETE_SELF); g_config_wd_noti = wd; g_config_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ, @@ -526,6 +567,7 @@ int __tts_config_set_auto_language() char temp_lang[6] = {'\0', }; strncpy(temp_lang, value, 5); free(value); + value = NULL; if (true == __tts_config_mgr_check_lang_is_valid(g_config_info->engine_id, temp_lang, g_config_info->type)) { /* tts default voice change */ @@ -545,8 +587,9 @@ int __tts_config_set_auto_language() before_lang = strdup(g_config_info->language); before_type = g_config_info->type; - free(g_config_info->language); - g_config_info->language = strdup(temp_lang); + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, temp_lang, sizeof(g_language) - 1); SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Config] Default voice : lang(%s) type(%d)", g_config_info->language, g_config_info->type); @@ -573,6 +616,7 @@ int __tts_config_set_auto_language() if (NULL != before_lang) { free(before_lang); + before_lang = NULL; } } else { /* Display language is not valid */ @@ -615,14 +659,15 @@ int __tts_config_set_auto_language() iter = g_slist_next(iter); } - if (NULL != g_config_info->language) { - free(g_config_info->language); - g_config_info->language = strdup(tmp_language); - } + + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, tmp_language, sizeof(g_language) - 1); g_config_info->type = tmp_type; free(tmp_language); + tmp_language = NULL; } return 0; @@ -725,29 +770,28 @@ void __tts_config_release_engine() int __tts_config_mgr_get_engine_info() { DIR *dp = NULL; - int ret = -1; - struct dirent entry; struct dirent *dirp = NULL; char filepath[512] = {'\0',}; int filesize; tts_engine_info_s* info = NULL; + __tts_config_release_engine(); g_engine_list = NULL; + __tts_config_mgr_unregister_engine_config_updated_event(); - /* Get engine info from default engine directory */ + /* Copy default info directory to download directory */ dp = opendir(TTS_DEFAULT_ENGINE_INFO); if (NULL == dp) { - SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] No downloadable directory : %s", TTS_DEFAULT_ENGINE_INFO); + SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] No default directory : %s", TTS_DEFAULT_ENGINE_INFO); } else { do { - ret = readdir_r(dp, &entry, &dirp); - if (0 != ret) { - SLOG(LOG_ERROR, tts_tag(), "[CONFIG] Fail to read directory"); - break; - } + dirp = readdir(dp); if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + filesize = strlen(TTS_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 2; if (filesize >= 512) { SECURE_SLOG(LOG_ERROR, tts_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); @@ -760,8 +804,49 @@ int __tts_config_mgr_get_engine_info() SECURE_SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] Filepath(%s)", filepath); + char dest[512] = {'\0',}; + snprintf(dest, 512, "%s/%s", TTS_DOWNLOAD_ENGINE_INFO, dirp->d_name); + + if (0 != access(dest, F_OK)) { + if (0 != tts_parser_copy_xml(filepath, dest)) { + SLOG(LOG_ERROR, tts_tag(), "[CONFIG ERROR] Fail to copy engine info"); + } + } + } + } while (NULL != dirp); + + closedir(dp); + } + + /* Get engine info from default engine directory */ + dp = opendir(TTS_DOWNLOAD_ENGINE_INFO); + if (NULL == dp) { + SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] No downloadable directory : %s", TTS_DOWNLOAD_ENGINE_INFO); + } else { + do { + dirp = readdir(dp); + + if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + + filesize = strlen(TTS_DOWNLOAD_ENGINE_INFO) + strlen(dirp->d_name) + 2; + if (filesize >= 512) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); + closedir(dp); + return -1; + } + + memset(filepath, '\0', 512); + snprintf(filepath, 512, "%s/%s", TTS_DOWNLOAD_ENGINE_INFO, dirp->d_name); + + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] Filepath(%s)", filepath); + if (0 == tts_parser_get_engine_info(filepath, &info)) { g_engine_list = g_slist_append(g_engine_list, info); + if (0 != __tts_config_mgr_register_engine_config_updated_event(filepath)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register engine config updated event"); + } } } } while (NULL != dirp); @@ -779,17 +864,19 @@ int __tts_config_mgr_get_engine_info() static Eina_Bool __tts_config_mgr_engine_config_inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler) { - SLOG(LOG_DEBUG, tts_tag(), "===== Engine config updated callback event"); + SLOG(LOG_DEBUG, tts_tag(), "@@@ Engine config updated callback event"); + + tts_engine_inotify_s *ino = (tts_engine_inotify_s *)data; + int dir_fd = ino->dir_fd; int length; struct inotify_event event; memset(&event, '\0', sizeof(struct inotify_event)); - length = read(g_dir_fd, &event, sizeof(struct inotify_event)); + length = read(dir_fd, &event, sizeof(struct inotify_event)); if (0 > length) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty Inotify event"); - SLOG(LOG_DEBUG, tts_tag(), "====="); - SLOG(LOG_DEBUG, tts_tag(), " "); + SLOG(LOG_DEBUG, tts_tag(), "@@@"); return ECORE_CALLBACK_DONE; } @@ -815,58 +902,118 @@ static Eina_Bool __tts_config_mgr_engine_config_inotify_event_callback(void* dat } else { SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Saved default voice : lang(%s), type(%d)", g_config_info->language, g_config_info->type); } - if (NULL != temp_lang) free(temp_lang); + if (NULL != temp_lang) { + free(temp_lang); + temp_lang = NULL; + } + } + + GSList *iter = NULL; + tts_config_client_s* temp_client = NULL; + /* Call all callbacks of client*/ + iter = g_slist_nth(g_config_client_list, 0); + + while (NULL != iter) { + temp_client = iter->data; + + if (NULL != temp_client) { + if (NULL != temp_client->engine_cb) { + SECURE_SLOG(LOG_DEBUG, tts_tag(), "Engine changed callback : uid(%d)", temp_client->uid); + temp_client->engine_cb(g_config_info->engine_id, g_config_info->setting, + g_config_info->language, g_config_info->type, + g_config_info->auto_voice, g_config_info->credential, temp_client->user_data); + } + } + + iter = g_slist_next(iter); } } else { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Undefined event"); } - SLOG(LOG_DEBUG, tts_tag(), "====="); - SLOG(LOG_DEBUG, tts_tag(), " "); + SLOG(LOG_DEBUG, tts_tag(), "@@@"); return ECORE_CALLBACK_PASS_ON; } -static int __tts_config_mgr_register_engine_config_updated_event() +static int __tts_config_mgr_register_engine_config_updated_event(const char* path) { + if (NULL == path) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Path is NULL"); + return -1; + } + /* For engine directory monitoring */ - g_dir_fd = inotify_init(); - if (g_dir_fd < 0) { + tts_engine_inotify_s *ino = (tts_engine_inotify_s *)calloc(1, sizeof(tts_engine_inotify_s)); + if (NULL == ino) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory"); + return -1; + } + + ino->dir_fd = inotify_init(); + if (ino->dir_fd < 0) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to init inotify"); + free(ino); + ino = NULL; + return -1; } - /* FIX_ME *//* It doesn't need check engine directory, because daemon will change engine-process */ - g_dir_wd = inotify_add_watch(g_dir_fd, TTS_DEFAULT_ENGINE_INFO, IN_CLOSE_WRITE); - if (g_dir_wd < 0) { + ino->dir_wd = inotify_add_watch(ino->dir_fd, path, IN_CLOSE_WRITE); + SLOG(LOG_DEBUG, tts_tag(), "Add inotify watch(%s)", path); + if (ino->dir_wd < 0) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to add watch"); + free(ino); + ino = NULL; return -1; } - g_dir_fd_handler = ecore_main_fd_handler_add(g_dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)__tts_config_mgr_engine_config_inotify_event_callback, NULL, NULL, NULL); - if (NULL == g_dir_fd_handler) { + ino->dir_fd_handler = ecore_main_fd_handler_add(ino->dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)__tts_config_mgr_engine_config_inotify_event_callback, (void *)ino, NULL, NULL); + if (NULL == ino->dir_fd_handler) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to add fd handler"); + free(ino); + ino = NULL; return -1; } /* Set non-blocking mode of file */ int value; - value = fcntl(g_dir_fd, F_GETFL, 0); + value = fcntl(ino->dir_fd, F_GETFL, 0); value |= O_NONBLOCK; - if (0 > fcntl(g_dir_fd, F_SETFL, value)) { + if (0 > fcntl(ino->dir_fd, F_SETFL, value)) { SLOG(LOG_WARN, tts_tag(), "[WARNING] Fail to set non-block mode"); } + g_ino_list = g_list_append(g_ino_list, ino); + return 0; } static int __tts_config_mgr_unregister_engine_config_updated_event() { - /* delete inotify variable */ - ecore_main_fd_handler_del(g_dir_fd_handler); - inotify_rm_watch(g_dir_fd, g_dir_wd); - close(g_dir_fd); + /* delete all inotify variable */ + if (0 < g_list_length(g_ino_list)) { + GList *iter = NULL; + iter = g_list_first(g_ino_list); + + while (NULL != iter) { + tts_engine_inotify_s *tmp = iter->data; + + if (NULL != tmp) { + ecore_main_fd_handler_del(tmp->dir_fd_handler); + inotify_rm_watch(tmp->dir_fd, tmp->dir_wd); + close(tmp->dir_fd); + + free(tmp); + tmp = NULL; + } + + g_ino_list = g_list_remove_link(g_ino_list, iter); + + iter = g_list_first(g_ino_list); + } + } return 0; } @@ -899,6 +1046,12 @@ int tts_config_mgr_initialize(int uid) return TTS_CONFIG_ERROR_OUT_OF_MEMORY; } temp_client->uid = uid; + temp_client->engine_cb = NULL; + temp_client->voice_cb = NULL; + temp_client->speech_cb = NULL; + temp_client->pitch_cb = NULL; + temp_client->screen_cb = NULL; + temp_client->user_data = NULL; g_config_client_list = g_slist_append(g_config_client_list, temp_client); @@ -911,6 +1064,12 @@ int tts_config_mgr_initialize(int uid) return TTS_CONFIG_ERROR_OUT_OF_MEMORY; } temp_client->uid = uid; + temp_client->engine_cb = NULL; + temp_client->voice_cb = NULL; + temp_client->speech_cb = NULL; + temp_client->pitch_cb = NULL; + temp_client->screen_cb = NULL; + temp_client->user_data = NULL; g_config_client_list = g_slist_append(g_config_client_list, temp_client); } @@ -918,12 +1077,43 @@ int tts_config_mgr_initialize(int uid) if (0 != access(TTS_CONFIG_BASE, F_OK)) { if (0 != mkdir(TTS_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to make directory : %s", TTS_CONFIG_BASE); - return -1; + __tts_config_release_client(uid); + return TTS_CONFIG_ERROR_OPERATION_FAILED; } else { SLOG(LOG_DEBUG, tts_tag(), "Success to make directory : %s", TTS_CONFIG_BASE); } } + if (0 != access(TTS_HOME, F_OK)) { + if (0 != mkdir(TTS_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to make directory : %s", TTS_HOME); + __tts_config_release_client(uid); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "Success to make directory : %s", TTS_HOME); + } + } + + if (0 != access(TTS_DOWNLOAD_BASE, F_OK)) { + if (0 != mkdir(TTS_DOWNLOAD_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to make directory : %s", TTS_DOWNLOAD_BASE); + __tts_config_release_client(uid); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "Success to make directory : %s", TTS_DOWNLOAD_BASE); + } + } + + if (0 != access(TTS_DOWNLOAD_ENGINE_INFO, F_OK)) { + if (0 != mkdir(TTS_DOWNLOAD_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to make directory : %s", TTS_DOWNLOAD_ENGINE_INFO); + __tts_config_release_client(uid); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "Success to make directory : %s", TTS_DOWNLOAD_ENGINE_INFO); + } + } + if (0 != __tts_config_mgr_get_engine_info()) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get engine info"); __tts_config_release_client(uid); @@ -946,6 +1136,7 @@ int tts_config_mgr_initialize(int uid) __tts_config_release_client(uid); __tts_config_release_engine(); tts_parser_unload_config(g_config_info); + g_config_info = NULL; return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND; } @@ -962,24 +1153,26 @@ int tts_config_mgr_initialize(int uid) __tts_config_release_client(uid); __tts_config_release_engine(); tts_parser_unload_config(g_config_info); + g_config_info = NULL; return TTS_CONFIG_ERROR_OPERATION_FAILED; } if (NULL != tmp_language) { - if (NULL != g_config_info->language) { - free(g_config_info->language); - g_config_info->language = strdup(tmp_language); - } + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, tmp_language, sizeof(g_language) - 1); g_config_info->type = tmp_type; free(tmp_language); + tmp_language = NULL; if (0 != tts_parser_set_voice(g_config_info->language, g_config_info->type)) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to save config"); __tts_config_release_client(uid); __tts_config_release_engine(); tts_parser_unload_config(g_config_info); + g_config_info = NULL; return TTS_CONFIG_ERROR_OPERATION_FAILED; } } @@ -987,7 +1180,7 @@ int tts_config_mgr_initialize(int uid) } /* print daemon config */ - SLOG(LOG_DEBUG, tts_tag(), "== TTS config =="); + SLOG(LOG_DEBUG, tts_tag(), "@@@ TTS config @@@"); SECURE_SLOG(LOG_DEBUG, tts_tag(), " engine : %s", g_config_info->engine_id); SECURE_SLOG(LOG_DEBUG, tts_tag(), " setting : %s", g_config_info->setting); SECURE_SLOG(LOG_DEBUG, tts_tag(), " auto voice : %s", g_config_info->auto_voice ? "on" : "off"); @@ -995,13 +1188,14 @@ int tts_config_mgr_initialize(int uid) SECURE_SLOG(LOG_DEBUG, tts_tag(), " voice type : %d", g_config_info->type); SECURE_SLOG(LOG_DEBUG, tts_tag(), " speech rate : %d", g_config_info->speech_rate); SECURE_SLOG(LOG_DEBUG, tts_tag(), " pitch : %d", g_config_info->pitch); - SLOG(LOG_DEBUG, tts_tag(), "================="); + SLOG(LOG_DEBUG, tts_tag(), "@@@@@"); if (0 != __tts_config_mgr_register_config_event()) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register config event"); __tts_config_release_client(uid); __tts_config_release_engine(); tts_parser_unload_config(g_config_info); + g_config_info = NULL; return TTS_CONFIG_ERROR_OPERATION_FAILED; } @@ -1010,14 +1204,14 @@ int tts_config_mgr_initialize(int uid) vconf_notify_key_changed(TTS_ACCESSIBILITY_KEY, __tts_config_screen_reader_changed_cb, NULL); /* For engine directory monitoring */ - if (0 != __tts_config_mgr_register_engine_config_updated_event()) { - SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register engine config updated event"); - __tts_config_release_client(uid); - __tts_config_release_engine(); - tts_parser_unload_config(g_config_info); - __tts_config_mgr_unregister_config_event(); - return TTS_CONFIG_ERROR_OPERATION_FAILED; - } + //if (0 != __tts_config_mgr_register_engine_config_updated_event()) { + // SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register engine config updated event"); + // __tts_config_release_client(uid); + // __tts_config_release_engine(); + // tts_parser_unload_config(g_config_info); + // __tts_config_mgr_unregister_config_event(); + // return TTS_CONFIG_ERROR_OPERATION_FAILED; + //} return 0; } @@ -1033,6 +1227,7 @@ int tts_config_mgr_finalize(int uid) __tts_config_release_engine(); tts_parser_unload_config(g_config_info); + g_config_info = NULL; __tts_config_mgr_unregister_engine_config_updated_event(); @@ -1230,6 +1425,61 @@ int tts_config_mgr_get_engine(char** engine) return TTS_CONFIG_ERROR_OPERATION_FAILED; } +int __tts_set_buxtonkey(const char* engine) +{ + /* Set vconfkey */ + struct buxton_client * bux_cli; + struct buxton_layer * bux_layer; + struct buxton_value * bux_val; + + int ret = buxton_open(&bux_cli, NULL, NULL); + if (0 != ret) { + SLOG(LOG_ERROR, tts_tag(), "[DBUS-BUXTON2] buxton_open failed!! (%d)", ret); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + bux_layer = buxton_create_layer("system"); + if (NULL == bux_layer) { + SLOG(LOG_ERROR, tts_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL"); + buxton_close(bux_cli); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + bux_val = buxton_value_create_string(engine); + if (NULL == bux_val) { + SLOG(LOG_ERROR, tts_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL"); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer)); + } + + ret = buxton_set_value_sync(bux_cli, bux_layer, TTS_ENGINE_DB_DEFAULT, bux_val); + if (0 != ret) { + SLOG(LOG_ERROR, tts_tag(), "[DBUS-BUXTON2] buxton_set_value_sync failed!! (%d)", ret); + buxton_value_free(bux_val); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + + bux_cli = NULL; + bux_layer = NULL; + bux_val = NULL; + + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %d, %s", ret, TTS_ENGINE_DB_DEFAULT); + } + + buxton_value_free(bux_val); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + + bux_cli = NULL; + bux_layer = NULL; + bux_val = NULL; + + return TTS_CONFIG_ERROR_NONE; +} + int tts_config_mgr_set_engine(const char* engine) { if (0 >= g_slist_length(g_config_client_list)) { @@ -1241,10 +1491,8 @@ int tts_config_mgr_set_engine(const char* engine) return TTS_CONFIG_ERROR_INVALID_PARAMETER; /* Check current engine id with new engine id */ - if (NULL != g_config_info->engine_id) { - if (0 == strcmp(g_config_info->engine_id, engine)) - return 0; - } + if (0 == strcmp(g_config_info->engine_id, engine)) + return 0; if (0 >= g_slist_length(g_engine_list)) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!"); @@ -1253,6 +1501,12 @@ int tts_config_mgr_set_engine(const char* engine) SLOG(LOG_DEBUG, tts_tag(), "New engine id : %s", engine); + int ret = __tts_set_buxtonkey(engine); + if (0 != ret) { + SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] set_buxtonkey Fail!!"); + return ret; + } + GSList *iter = NULL; tts_engine_info_s *engine_info = NULL; bool is_valid_engine = false; @@ -1275,16 +1529,15 @@ int tts_config_mgr_set_engine(const char* engine) continue; } - if (NULL != g_config_info->engine_id) - free(g_config_info->engine_id); - - g_config_info->engine_id = strdup(engine); + memset(g_engine_id, '\0', sizeof(g_engine_id)); + g_config_info->engine_id = g_engine_id; + strncpy(g_config_info->engine_id, engine, sizeof(g_engine_id) - 1); - if (NULL != g_config_info->setting) - free(g_config_info->setting); - - if (NULL != engine_info->setting) - g_config_info->setting = strdup(engine_info->setting); + if (NULL != engine_info->setting) { + memset(g_setting, '\0', sizeof(g_setting)); + g_config_info->setting = g_setting; + strncpy(g_config_info->setting, engine_info->setting, sizeof(g_setting) - 1); + } /* Engine is valid*/ GSList *iter_voice = NULL; @@ -1318,17 +1571,17 @@ int tts_config_mgr_set_engine(const char* engine) } if (false == is_valid_voice) { - if (NULL != g_config_info->language) { - free(g_config_info->language); - - iter_voice = g_slist_nth(engine_info->voices, 0); - if (NULL != iter_voice) { - voice = iter_voice->data; - if (NULL != voice) { - if (NULL != voice->language) - g_config_info->language = strdup(voice->language); - g_config_info->type = voice->type; - } + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + + iter_voice = g_slist_nth(engine_info->voices, 0); + if (NULL != iter_voice) { + voice = iter_voice->data; + if (NULL != voice) { + if (NULL != voice->language) + strncpy(g_config_info->language, voice->language, sizeof(g_language) - 1); + + g_config_info->type = voice->type; } } } @@ -1428,7 +1681,7 @@ int tts_config_mgr_get_voice(char** language, int* type) if (NULL == language || NULL == type) return TTS_CONFIG_ERROR_INVALID_PARAMETER; - if (NULL != g_config_info->language) { + if (0 != strlen(g_config_info->language)) { *language = strdup(g_config_info->language); *type = g_config_info->type; } else { @@ -1457,19 +1710,15 @@ int tts_config_mgr_set_voice(const char* language, int type) } /* Check language is valid */ - if (NULL != g_config_info->language) { - if (0 != tts_parser_set_voice(language, type)) { - SLOG(LOG_ERROR, tts_tag(), "Fail to save default voice"); - return TTS_CONFIG_ERROR_OPERATION_FAILED; - } - free(g_config_info->language); - g_config_info->language = strdup(language); - g_config_info->type = type; - - } else { - SLOG(LOG_ERROR, tts_tag(), "language is NULL"); + if (0 != tts_parser_set_voice(language, type)) { + SLOG(LOG_ERROR, tts_tag(), "Fail to save default voice"); return TTS_CONFIG_ERROR_OPERATION_FAILED; } + memset(g_language, '\0', sizeof(g_language)); + g_config_info->language = g_language; + strncpy(g_config_info->language, language, sizeof(g_language) - 1); + + g_config_info->type = type; return 0; } @@ -1688,7 +1937,7 @@ bool tts_config_check_default_voice_is_valid(const char* language, int type) if (NULL == language) return false; - if (NULL == g_config_info->engine_id) { + if (0 == strlen(g_config_info->engine_id)) { SLOG(LOG_ERROR, tts_tag(), "[ERROR] Default engine id is NULL"); return false; } @@ -1794,3 +2043,53 @@ int __tts_config_mgr_print_engine_info() return 0; } + +int tts_config_mgr_get_max_text_size(unsigned int* size) +{ + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, tts_tag(), "Not initialized"); + return TTS_CONFIG_ERROR_INVALID_PARAMETER; + } + + if (NULL == size) { + return TTS_CONFIG_ERROR_INVALID_PARAMETER; + } + + GSList *iter = NULL; + tts_engine_info_s *engine_info = NULL; + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!"); + return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + /* Get a first item */ + iter = g_slist_nth(g_engine_list, 0); + + while (NULL != iter) { + engine_info = iter->data; + + if (NULL == engine_info) { + SLOG(LOG_ERROR, tts_tag(), "engine info is NULL"); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + + if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) { + iter = g_slist_next(iter); + continue; + } + + break; + } + + if (NULL == engine_info) { + SLOG(LOG_ERROR, tts_tag(), "engine info is NULL"); + return TTS_CONFIG_ERROR_OPERATION_FAILED; + } + + *size = engine_info->text_size; + SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Max text size is %d.", *size); + + return 0; +} +