Add to check RW config file and reset config info
[platform/core/uifw/tts.git] / common / tts_config_mgr.c
index be4ce0b..1522950 100644 (file)
@@ -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 <unistd.h>
 #include <sys/inotify.h>
 #include <vconf.h>
+#include <buxton2.h>
 
 #include "tts_config_mgr.h"
 #include "tts_config_parser.h"
@@ -33,7 +34,7 @@ typedef struct {
        tts_config_screen_reader_changed_cb     screen_cb;
        tts_config_pitch_changed_cb             pitch_cb;
        void*   user_data;
-}tts_config_client_s;
+} tts_config_client_s;
 
 extern char* tts_tag();
 
@@ -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,13 +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);
+       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->engine_id)   free(g_config_info->engine_id);
-       if (NULL != g_config_info->setting)     free(g_config_info->setting);
+       if (NULL == g_config_info) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine info in list");
+               return TTS_CONFIG_ERROR_OPERATION_FAILED;
+       }
 
-       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);
 
@@ -111,21 +135,23 @@ int __tts_config_mgr_check_engine_is_valid(const char* engine_id)
        while (NULL != iter_voice) {
                /*Get handle data from list*/
                voice = iter_voice->data;
-               
-               if (NULL != voice && NULL != g_config_info) {
-                       if (NULL != voice->language && NULL != g_config_info->language) {
+
+               if (NULL != voice) {
+                       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);
+                                               break;
                                        }
-                                       break;
                                }
                        }
                }
@@ -135,19 +161,27 @@ 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, 
+       if (0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting, 
                g_config_info->language, g_config_info->type)) {
                SLOG(LOG_ERROR, tts_tag(), " Fail to save config");
                return TTS_CONFIG_ERROR_OPERATION_FAILED;
@@ -195,7 +229,7 @@ bool __tts_config_mgr_check_lang_is_valid(const char* engine_id, const char* lan
                        iter = g_slist_next(iter);
                        return false;
                }
-               
+
                /* Get a first item */
                iter_voice = g_slist_nth(engine_info->voices, 0);
 
@@ -211,7 +245,7 @@ bool __tts_config_mgr_check_lang_is_valid(const char* engine_id, const char* lan
                                        }
                                }
                        }
-                       
+
                        /*Get next item*/
                        iter_voice = g_slist_next(iter_voice);
                        i++;
@@ -237,7 +271,7 @@ int __tts_config_mgr_select_lang(const char* engine_id, char** language, int* ty
                SLOG(LOG_ERROR, tts_tag(), "There is no engine!!");
                return false;
        }
-       
+
        /* Get a first item */
        iter = g_slist_nth(g_engine_list, 0);
 
@@ -248,7 +282,7 @@ int __tts_config_mgr_select_lang(const char* engine_id, char** language, int* ty
                        SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
                        return false;
                }
-               
+
                if (0 != strcmp(engine_id, engine_info->uuid)) {
                        iter = g_slist_next(iter);
                        continue;
@@ -296,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;
@@ -305,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;
        }
 
@@ -329,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);
@@ -354,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);
                                        }
                                }
 
@@ -374,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;
@@ -402,9 +432,10 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl
 
                                iter = g_slist_next(iter);
                        }
-                       
+
                        if (NULL != before_lang) {
                                free(before_lang);
+                               before_lang = NULL;
                        }
                }
 
@@ -452,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;
 }
@@ -478,11 +523,11 @@ 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, 
-               (Ecore_Fd_Cb)tts_config_mgr_inotify_event_cb, NULL, NULL, NULL);                
+       g_config_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
+               (Ecore_Fd_Cb)tts_config_mgr_inotify_event_cb, NULL, NULL, NULL);
        if (NULL == g_config_fd_handler_noti) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get handler_noti");
                return -1;
@@ -492,7 +537,7 @@ int __tts_config_mgr_register_config_event()
        int value;
        value = fcntl(fd, F_GETFL, 0);
        value |= O_NONBLOCK;
-       
+
        if (0 > fcntl(fd, F_SETFL, value)) {
                SLOG(LOG_WARN, tts_tag(), "[WARNING] Fail to set non-block mode");
        }
@@ -510,51 +555,6 @@ int __tts_config_mgr_unregister_config_event()
        return 0;
 }
 
-void __tts_config_speech_rate_key_changed_cb(keynode_t *key, void *data)
-{
-       int ret;
-       int speech_rate;
-       ret = vconf_get_int(TTS_ACCESSIBILITY_SPEED_KEY, &speech_rate);
-
-       if (0 != ret) {
-               SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Fail to get speech rate");
-               return;
-       }
-       
-       /* Check speech rate is valid */
-       if (TTS_CONFIG_SPEED_MIN <= speech_rate && speech_rate <= TTS_CONFIG_SPEED_MAX) {
-               SLOG(LOG_DEBUG, tts_tag(), "[Config] Speech rate  : %d", speech_rate);
-               
-               if (g_config_info->speech_rate != speech_rate) {
-                       g_config_info->speech_rate = speech_rate;
-
-                       tts_parser_set_speech_rate(g_config_info->speech_rate);
-
-                       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->speech_cb) {
-                                               temp_client->speech_cb(g_config_info->speech_rate, temp_client->user_data);
-                                       }
-                               }
-
-                               iter = g_slist_next(iter);
-                       }
-               }
-       } else {
-               SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Speech rate is not valid : %d", speech_rate);
-       }
-
-       return;
-}
-
 int __tts_config_set_auto_language()
 {
        char* value = NULL;
@@ -567,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 */
@@ -586,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);
@@ -614,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 */
@@ -656,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;
@@ -682,7 +686,7 @@ void __tts_config_screen_reader_changed_cb(keynode_t *key, void *data)
 {
        int ret;
        int screen_reader;
-       ret = vconf_get_int(TTS_ACCESSIBILITY_KEY, &screen_reader);
+       ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
        if (0 != ret) {
                SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Fail to get screen reader");
                return;
@@ -723,6 +727,7 @@ int __tts_config_release_client(int uid)
                                if (uid == temp_client->uid) {
                                        g_config_client_list = g_slist_remove(g_config_client_list, temp_client);
                                        free(temp_client);
+                                       temp_client = NULL;
                                        break;
                                }
                        }
@@ -765,43 +770,47 @@ 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);
                                        closedir(dp);
                                        return -1;
                                }
-                               
+
                                memset(filepath, '\0', 512);
                                snprintf(filepath, 512, "%s/%s", TTS_DEFAULT_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);
+                               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);
@@ -809,55 +818,35 @@ int __tts_config_mgr_get_engine_info()
                closedir(dp);
        }
 
-       /* Get engine info from downloadable engine directory */
+       /* 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 {
-                       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_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)) {
-                                       /* Compare id */
-                                       GSList *iter = NULL;
-                                       tts_engine_info_s *engine_info = NULL;
-
-                                       /* Get a first item */
-                                       iter = g_slist_nth(g_engine_list, 0);
-
-                                       while (NULL != iter) {
-                                               engine_info = iter->data;
-
-                                               if (NULL != engine_info) {
-                                                       /* Remove old engine info */
-                                                       if (0 == strncmp(engine_info->uuid, info->uuid, strlen(engine_info->uuid))) {
-                                                               SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] Remove old engine : %s", engine_info->name);
-                                                               g_engine_list = g_slist_remove(g_engine_list, engine_info);
-                                                               tts_parser_free_engine_info(engine_info);
-                                                               break;
-                                                       }
-                                               }
-                                               iter = iter->next;
-                                       }
-
                                        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);
@@ -875,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;
        }
 
@@ -904,64 +895,125 @@ static Eina_Bool __tts_config_mgr_engine_config_inotify_event_callback(void* dat
                        if (0 != ret) {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get voice");
                        }
-                       
+
                        ret = tts_config_mgr_set_voice(temp_lang, temp_type);
                        if (0 != ret) {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to set voice");
                        } 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;
        }
 
-       g_dir_wd = inotify_add_watch(g_dir_fd, TTS_OPT_BASE"/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;
 }
@@ -989,7 +1041,17 @@ int tts_config_mgr_initialize(int uid)
                }
 
                temp_client = (tts_config_client_s*)calloc(1, sizeof(tts_config_client_s));
+               if (NULL == temp_client) {
+                       SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory");
+                       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);
 
@@ -997,11 +1059,61 @@ int tts_config_mgr_initialize(int uid)
                return 0;
        } else {
                temp_client = (tts_config_client_s*)calloc(1, sizeof(tts_config_client_s));
+               if (NULL == temp_client) {
+                       SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory");
+                       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);
        }
 
+       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);
+                       __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);
@@ -1015,18 +1127,19 @@ int tts_config_mgr_initialize(int uid)
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse configure information");
                __tts_config_release_client(uid);
                __tts_config_release_engine();
-               return TTS_CONFIG_ERROR_OPERATION_FAILED; 
+               return TTS_CONFIG_ERROR_OPERATION_FAILED;
        }
-       
+
        /* Check whether engine id is valid */
        if (0 != __tts_config_mgr_check_engine_is_valid(g_config_info->engine_id)) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get default engine");
                __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;
        }
-       
+
        if (true == g_config_info->auto_voice) {
                /* Check language with display language */
                __tts_config_set_auto_language();
@@ -1040,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;
                                }
                        }
@@ -1065,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");
@@ -1073,30 +1188,30 @@ 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;
        }
 
        /* Register to detect display language change */
        vconf_notify_key_changed(TTS_LANGSET_KEY, __tts_config_display_language_changed_cb, NULL);
-       vconf_notify_key_changed(TTS_ACCESSIBILITY_SPEED_KEY, __tts_config_speech_rate_key_changed_cb, NULL);
        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;
 }
@@ -1107,16 +1222,18 @@ int tts_config_mgr_finalize(int uid)
                return 0;
        }
 
+       tts_config_mgr_unset_callback(uid);
+
        __tts_config_release_engine();
 
        tts_parser_unload_config(g_config_info);
+       g_config_info = NULL;
 
        __tts_config_mgr_unregister_engine_config_updated_event();
 
        __tts_config_mgr_unregister_config_event();
 
        vconf_ignore_key_changed(TTS_LANGSET_KEY, __tts_config_display_language_changed_cb);
-       vconf_ignore_key_changed(TTS_ACCESSIBILITY_SPEED_KEY, __tts_config_speech_rate_key_changed_cb);
        vconf_ignore_key_changed(TTS_ACCESSIBILITY_KEY, __tts_config_screen_reader_changed_cb);
 
        return 0;
@@ -1299,7 +1416,7 @@ int tts_config_mgr_get_engine(char** engine)
                        }
                        iter = g_slist_next(iter);
                }
-               
+
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Current engine id is not valid");
        } else {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Engine id is NULL");
@@ -1308,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)) {
@@ -1319,7 +1491,7 @@ int tts_config_mgr_set_engine(const char* engine)
                return TTS_CONFIG_ERROR_INVALID_PARAMETER;
 
        /* Check current engine id with new engine id */
-       if (0 == strcmp(g_config_info->engine_id, engine)) 
+       if (0 == strcmp(g_config_info->engine_id, engine))
                return 0;
 
        if (0 >= g_slist_length(g_engine_list)) {
@@ -1329,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;
@@ -1351,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);
-
-               if (NULL != g_config_info->setting)
-                       free(g_config_info->setting);
+               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 != 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;
@@ -1373,7 +1550,7 @@ int tts_config_mgr_set_engine(const char* engine)
                while (NULL != iter_voice) {
                        /*Get handle data from list*/
                        voice = iter_voice->data;
-                       
+
                        if (NULL != voice) {
                                if (NULL == voice->language)
                                        continue;
@@ -1383,13 +1560,7 @@ int tts_config_mgr_set_engine(const char* engine)
                                        if (voice->type == g_config_info->type) {
                                                /* language is valid */
                                                is_valid_voice = true;
-
-                                               if (NULL != g_config_info->language) {
-                                                       free(g_config_info->language);
-
-                                                       g_config_info->language = strdup(voice->language);
-                                                       g_config_info->type = voice->type;
-                                               }
+                                               g_config_info->type = voice->type;
                                        }
                                        break;
                                }
@@ -1400,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;
                                }
                        }
                }
@@ -1425,8 +1596,8 @@ int tts_config_mgr_set_engine(const char* engine)
                SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Setting : %s", g_config_info->setting);
                SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Language : %s", g_config_info->language);
                SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Type : %d", g_config_info->type);
-               
-               if ( 0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting, 
+
+               if (0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting,
                        g_config_info->language, g_config_info->type)) {
                                SLOG(LOG_ERROR, tts_tag(), " Fail to save config");
                                return TTS_CONFIG_ERROR_OPERATION_FAILED;
@@ -1472,7 +1643,7 @@ int tts_config_mgr_get_voice_list(const char* engine_id, tts_config_supported_vo
 
                GSList *iter_voice = NULL;
                tts_config_voice_s* voice = NULL;
-               
+
                /* Get a first item */
                iter_voice = g_slist_nth(engine_info->voices, 0);
 
@@ -1485,7 +1656,7 @@ int tts_config_mgr_get_voice_list(const char* engine_id, tts_config_supported_vo
                                if (false == callback(engine_info->uuid, voice->language, voice->type, user_data))
                                        break;
                        }
-                       
+
                        /*Get next item*/
                        iter_voice = g_slist_next(iter_voice);
                }
@@ -1510,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 {
@@ -1539,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;
 }
@@ -1600,7 +1767,7 @@ int tts_config_mgr_get_speech_rate(int* value)
                SLOG(LOG_ERROR, tts_tag(), "Not initialized");
                return TTS_CONFIG_ERROR_INVALID_PARAMETER;
        }
-       
+
        if (NULL == value) {
                return TTS_CONFIG_ERROR_INVALID_PARAMETER;
        }
@@ -1623,14 +1790,12 @@ int tts_config_mgr_set_speech_rate(int value)
                        SLOG(LOG_ERROR, tts_tag(), "Fail to save speech rate");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
-               
-               g_config_info->speech_rate = value;
 
-               vconf_set_int(TTS_ACCESSIBILITY_SPEED_KEY, value);
+               g_config_info->speech_rate = value;
        } else {
                SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Speech rate is invalid : %d", value);
        }
-       
+
        return 0;
 }
 
@@ -1663,7 +1828,7 @@ int tts_config_mgr_get_pitch(int* value)
                        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;
@@ -1695,7 +1860,7 @@ int tts_config_mgr_set_pitch(int value)
                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);
 
@@ -1706,7 +1871,7 @@ int tts_config_mgr_set_pitch(int value)
                        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;
@@ -1723,7 +1888,7 @@ int tts_config_mgr_set_pitch(int value)
                SLOG(LOG_ERROR, tts_tag(), "Fail to save speech rate");
                return TTS_CONFIG_ERROR_OPERATION_FAILED;
        }
-       
+
        g_config_info->pitch = value;
 
        return 0;
@@ -1739,7 +1904,7 @@ bool tts_config_check_default_engine_is_valid(const char* engine)
        if (NULL == engine)
                return false;
 
-       if (0 >= g_slist_length(g_engine_list)) 
+       if (0 >= g_slist_length(g_engine_list))
                return false;
 
        GSList *iter = NULL;
@@ -1772,12 +1937,12 @@ 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;
        }
 
-       if (0 >= g_slist_length(g_engine_list)) 
+       if (0 >= g_slist_length(g_engine_list))
                return false;
 
        GSList *iter = NULL;
@@ -1808,7 +1973,7 @@ bool tts_config_check_default_voice_is_valid(const char* language, int type)
 
                while (NULL != iter_voice) {
                        voice = iter_voice->data;
-                       
+
                        if (0 == strcmp(language, voice->language) && voice->type == type)
                                return true;
 
@@ -1840,7 +2005,7 @@ int __tts_config_mgr_print_engine_info()
 
        SLOG(LOG_DEBUG, tts_tag(), "--------------- engine list -----------------");
 
-       int i = 1;      
+       int i = 1;
        while (NULL != iter) {
                engine_info = iter->data;
 
@@ -1879,20 +2044,52 @@ int __tts_config_mgr_print_engine_info()
        return 0;
 }
 
-char* tts_config_get_message_path(int mode, int pid)
+int tts_config_mgr_get_max_text_size(unsigned int* size)
 {
-       char* path = NULL;
-       path = calloc(128, sizeof(char));
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, tts_tag(), "Not initialized");
+               return TTS_CONFIG_ERROR_INVALID_PARAMETER;
+       }
 
-       switch(mode) {
-       case 0: snprintf(path, 128, "%s%s_%d", MESSAGE_FILE_PATH_ROOT, MESSAGE_FILE_PREFIX_DEFAULT, pid);       break;
-       case 1: snprintf(path, 128, "%s%s_%d", MESSAGE_FILE_PATH_ROOT, MESSAGE_FILE_PREFIX_NOTIFICATION, pid);  break;
-       case 2: snprintf(path, 128, "%s%s_%d", MESSAGE_FILE_PATH_ROOT, MESSAGE_FILE_PREFIX_SCREEN_READER, pid); break;
-       default:
-               if (NULL != path)       free(path);
-               SLOG(LOG_ERROR, tts_tag(), "[Config] Invalid mode (%d)", mode);
-               return NULL;
+       if (NULL == size) {
+               return TTS_CONFIG_ERROR_INVALID_PARAMETER;
        }
 
-       return path;
-}
\ No newline at end of file
+       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;
+}
+