Invoke config changed callbacks directly 52/289452/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Fri, 24 Feb 2023 05:14:10 +0000 (14:14 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Tue, 7 Mar 2023 06:18:18 +0000 (15:18 +0900)
- Issue:
If the app changes the config using setting API, the framework did not
invoke config changed callbacks.

- Solution:
In previous code, tts_config_mgr module can knows the config changes by
checking the difference between the values in memory and config file.
However, the values in memory and config file were the same if the app
uses the setting API. This is because the setting API sets the value to
both memory and the file.
So, this patch adds a new logic for invoking the callacks. Through this
patch, tts_config_mgr module calls the related callbacks in case the app
changes the config itself.

Change-Id: If2da13a32e8e12b321812586e4c4bb93fd5f769e
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
common/tts_config_mgr.c

index fd65e85..7681be1 100644 (file)
@@ -43,18 +43,18 @@ typedef struct {
 } tts_config_client_s;
 
 typedef struct {
-       const char* engine_id;
-       const char* setting;
-       const char* language;
+       char* engine_id;
+       char* setting;
+       char* language;
        int voice_type;
        bool auto_voice;
        bool need_credential;
 } engine_changed_cb_parameter_s;
 
 typedef struct {
-       const char* before_language;
+       char* before_language;
        int before_voice_type;
-       const char* current_language;
+       char* current_language;
        int current_voice_type;
        bool auto_voice;
 } voice_changed_cb_parameter_s;
@@ -74,6 +74,12 @@ static int g_config_wd_noti;
 
 static int g_client_type = 0x0;
 
+static Ecore_Idler *g_engine_changed_event_idler = NULL;
+static Ecore_Idler *g_voice_changed_event_idler = NULL;
+static Ecore_Idler *g_speech_rate_changed_event_idler = NULL;
+static Ecore_Idler *g_pitch_changed_event_idler = NULL;
+static Ecore_Idler *g_bg_volume_ratio_changed_event_idler = NULL;
+
 /* For engine directory monitoring */
 typedef struct {
        Ecore_Fd_Handler* dir_fd_handler;
@@ -339,7 +345,19 @@ int __tts_config_mgr_select_lang(const char* engine_id, char** language, int* ty
        return TTS_CONFIG_ERROR_OPERATION_FAILED;
 }
 
-static void __invoke_engine_changed_cb(gpointer data, gpointer user_data)
+static inline void release_engine_changed_cb_params(engine_changed_cb_parameter_s *params)
+{
+       if (NULL == params) {
+               return;
+       }
+
+       free(params->engine_id);
+       free(params->setting);
+       free(params->language);
+       free(params);
+}
+
+static void invoke_engine_changed_cb(gpointer data, gpointer user_data)
 {
        tts_config_client_s* client = (tts_config_client_s*)data;
        engine_changed_cb_parameter_s* params = (engine_changed_cb_parameter_s*)user_data;
@@ -356,7 +374,61 @@ static void __invoke_engine_changed_cb(gpointer data, gpointer user_data)
        }
 }
 
-static void __invoke_voice_changed_cb(gpointer data, gpointer user_data)
+static Eina_Bool invoke_engine_changed_event_by_idler(void *data)
+{
+       engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)data;
+       if (NULL != params) {
+               SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Engine change(%s)", params->engine_id);
+
+               g_slist_foreach(g_config_client_list, invoke_engine_changed_cb, params);
+               release_engine_changed_cb_params(params);
+       }
+
+       g_engine_changed_event_idler = NULL;
+       return EINA_FALSE;
+}
+
+static inline void delete_engine_changed_event_invoker()
+{
+       if (NULL != g_engine_changed_event_idler) {
+               engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)ecore_idler_del(g_engine_changed_event_idler);
+               g_engine_changed_event_idler = NULL;
+               release_engine_changed_cb_params(params);
+       }
+}
+
+static void invoke_engine_changed_event(const char* engine_id, const char* setting, const char* language, int voice_type, bool auto_voice, bool need_credential)
+{
+       delete_engine_changed_event_invoker();
+
+       engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)calloc(1, sizeof(engine_changed_cb_parameter_s));
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+               return;
+       }
+
+       params->engine_id = strdup(engine_id);
+       params->setting = strdup(setting);
+       params->language = strdup(language);
+       params->voice_type = voice_type;
+       params->auto_voice = auto_voice;
+       params->need_credential = need_credential;
+       g_engine_changed_event_idler = ecore_idler_add(invoke_engine_changed_event_by_idler, params);
+}
+
+static inline void release_voice_changed_cb_params(voice_changed_cb_parameter_s *params)
+{
+       if (NULL == params) {
+               return;
+       }
+
+       free(params->before_language);
+       free(params->current_language);
+       free(params);
+}
+
+static void invoke_voice_changed_cb(gpointer data, gpointer user_data)
 {
        tts_config_client_s* client = (tts_config_client_s*)data;
        voice_changed_cb_parameter_s* params = (voice_changed_cb_parameter_s*)user_data;
@@ -373,7 +445,226 @@ static void __invoke_voice_changed_cb(gpointer data, gpointer user_data)
        }
 }
 
-Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
+static Eina_Bool invoke_voice_changed_event_by_idler(void *data)
+{
+       voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)data;
+       if (NULL != params) {
+               SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Voice change(%s, %d)", params->current_language, params->current_voice_type);
+
+               g_slist_foreach(g_config_client_list, invoke_voice_changed_cb, params);
+               release_voice_changed_cb_params(params);
+       }
+
+       g_voice_changed_event_idler = NULL;
+       return EINA_FALSE;
+}
+
+static inline void delete_voice_changed_event_invoker()
+{
+       if (NULL != g_voice_changed_event_idler) {
+               voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)ecore_idler_del(g_voice_changed_event_idler);
+               g_voice_changed_event_idler = NULL;
+               release_voice_changed_cb_params(params);
+       }
+}
+
+static void invoke_voice_changed_event(const char* before_language, int before_voice_type, const char* current_language, int current_voice_type, bool auto_voice)
+{
+       delete_voice_changed_event_invoker();
+
+       voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)calloc(1, sizeof(voice_changed_cb_parameter_s));
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+               return;
+       }
+
+       params->before_language = strdup(before_language);
+       params->before_voice_type = before_voice_type;
+       params->current_language = strdup(current_language);
+       params->current_voice_type = current_voice_type;
+       params->auto_voice = auto_voice;
+       g_voice_changed_event_idler = ecore_idler_add(invoke_voice_changed_event_by_idler, params);
+}
+
+static void invoke_speech_rate_changed_cb(gpointer data, gpointer user_data)
+{
+       tts_config_client_s* client = (tts_config_client_s*)data;
+       int* params = (int*)user_data;
+
+       if (NULL == client || NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+               return;
+       }
+
+       if (NULL != client->speech_cb) {
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate changed callback : uid(%u)", client->uid);
+               client->speech_cb(*params, client->user_data);
+       }
+}
+
+static Eina_Bool invoke_speech_rate_changed_event_by_idler(void *data)
+{
+       int *params = (int *)data;
+       if (NULL != params) {
+               SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate change(%d)", *params);
+
+               g_slist_foreach(g_config_client_list, invoke_speech_rate_changed_cb, params);
+               free(params);
+       }
+
+       g_speech_rate_changed_event_idler = NULL;
+       return EINA_FALSE;
+}
+
+static inline void delete_speech_rate_changed_event_invoker()
+{
+       if (NULL != g_speech_rate_changed_event_idler) {
+               int *params = (int *)ecore_idler_del(g_speech_rate_changed_event_idler);
+               g_speech_rate_changed_event_idler = NULL;
+               free(params);
+       }
+}
+
+static void invoke_speech_rate_changed_event(int speech_rate)
+{
+       delete_speech_rate_changed_event_invoker();
+
+       int *params = (int *)calloc(1, sizeof(int));
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+               return;
+       }
+
+       *params = speech_rate;
+       g_speech_rate_changed_event_idler = ecore_idler_add(invoke_speech_rate_changed_event_by_idler, params);
+}
+
+static void invoke_pitch_changed_cb(gpointer data, gpointer user_data)
+{
+       tts_config_client_s* client = (tts_config_client_s*)data;
+       int* params = (int*)user_data;
+
+       if (NULL == client || NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+               return;
+       }
+
+       if (NULL != client->pitch_cb) {
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch changed callback : uid(%u)", client->uid);
+               client->pitch_cb(*params, client->user_data);
+       }
+}
+
+static Eina_Bool invoke_pitch_changed_event_by_idler(void *data)
+{
+       int *params = (int *)data;
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is null. Invalid invocation");
+               g_pitch_changed_event_idler = NULL;
+               return EINA_FALSE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+       SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch change(%d)", *params);
+       g_slist_foreach(g_config_client_list, invoke_pitch_changed_cb, params);
+
+       free(params);
+       g_pitch_changed_event_idler = NULL;
+       return EINA_FALSE;
+}
+
+static inline void delete_pitch_changed_event_invoker()
+{
+       if (NULL != g_pitch_changed_event_idler) {
+               int *params = (int *)ecore_idler_del(g_pitch_changed_event_idler);
+               g_pitch_changed_event_idler = NULL;
+               free(params);
+       }
+}
+
+static void invoke_pitch_changed_event(int pitch)
+{
+       delete_pitch_changed_event_invoker();
+
+       int *params = (int *)calloc(1, sizeof(int));
+       if (NULL != params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+               return;
+       }
+
+       *params = pitch;
+       g_pitch_changed_event_idler = ecore_idler_add(invoke_pitch_changed_event_by_idler, params);
+}
+
+static void invoke_bg_volume_ratio_changed_cb(gpointer data, gpointer user_data)
+{
+       tts_config_client_s* client = (tts_config_client_s*)data;
+       double* params = (double*)user_data;
+
+       if (NULL == client || NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+               return;
+       }
+
+       if (NULL != client->bg_volume_ratio_cb) {
+               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Background volume ratio changed callback : uid(%u)", client->uid);
+               client->bg_volume_ratio_cb(*params, client->user_data);
+       }
+}
+
+static Eina_Bool invoke_bg_volume_ratio_changed_event_by_idler(void *data)
+{
+       double *params = (double *)data;
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is null. Invalid invocation");
+               g_bg_volume_ratio_changed_event_idler = NULL;
+               return EINA_FALSE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+       SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio change(%lf)", *params);
+       g_slist_foreach(g_config_client_list, invoke_bg_volume_ratio_changed_cb, params);
+
+       free(params);
+       g_bg_volume_ratio_changed_event_idler = NULL;
+       return EINA_FALSE;
+}
+
+static inline void delete_bg_volume_ratio_changed_event_invoker()
+{
+       if (NULL != g_bg_volume_ratio_changed_event_idler) {
+               double *params = (double *)ecore_idler_del(g_bg_volume_ratio_changed_event_idler);
+               g_bg_volume_ratio_changed_event_idler = NULL;
+               free(params);
+       }
+}
+
+static void invoke_bg_volume_ratio_changed_event(double bg_volume_ratio)
+{
+       delete_bg_volume_ratio_changed_event_invoker();
+
+       double *params = (double *)calloc(1, sizeof(double));
+       if (NULL == params) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+               return;
+       }
+
+       *params = bg_volume_ratio;
+       g_bg_volume_ratio_changed_event_idler = ecore_idler_add(invoke_bg_volume_ratio_changed_event_by_idler, params);
+}
+
+static void delete_all_event_invokers()
+{
+       delete_engine_changed_event_invoker();
+       delete_voice_changed_event_invoker();
+       delete_speech_rate_changed_event_invoker();
+       delete_pitch_changed_event_invoker();
+       delete_bg_volume_ratio_changed_event_invoker();
+}
+
+static Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
 {
        SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
 
@@ -405,9 +696,6 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl
                int pitch = -1;
                double bg_volume_ratio = -1;
 
-               GSList *iter = NULL;
-               tts_config_client_s* temp_client = NULL;
-
                if (0 != tts_parser_find_config_changed(&engine, &setting, &auto_voice, &lang, &voice_type, &speech_rate, &pitch, &bg_volume_ratio))
                        return ECORE_CALLBACK_PASS_ON;
 
@@ -417,19 +705,20 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl
                                memset(g_engine_id, '\0', sizeof(g_engine_id));
                                config_info.engine_id = g_engine_id;
                                strncpy(config_info.engine_id, engine, sizeof(g_engine_id) - 1);
+                               free(engine);
                        }
+
                        if (NULL != setting) {
                                memset(g_setting, '\0', sizeof(g_setting));
                                config_info.setting = g_setting;
                                strncpy(config_info.setting, setting, sizeof(g_setting) - 1);
+                               free(setting);
                        }
 
                        SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Engine change(%s)", config_info.engine_id);
 
                        /* Call all callbacks of client*/
-                       engine_changed_cb_parameter_s params = {config_info.engine_id, config_info.setting,config_info.language,
-                                       config_info.type, config_info.auto_voice, config_info.credential};
-                       g_slist_foreach(g_config_client_list, __invoke_engine_changed_cb, &params);
+                       invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
                }
 
                if (auto_voice != config_info.auto_voice) {
@@ -444,89 +733,33 @@ Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handl
                        SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Voice change(%s, %d)", config_info.language, config_info.type);
 
                        /* Call all callbacks of client*/
-                       voice_changed_cb_parameter_s params = {before_lang, before_type, config_info.language,
-                                       config_info.type, config_info.auto_voice};
-                       g_slist_foreach(g_config_client_list, __invoke_voice_changed_cb, &params);
+                       invoke_voice_changed_event(before_lang, before_type, config_info.language, config_info.type, config_info.auto_voice);
+                       free(lang);
                        free(before_lang);
                }
 
                if (-1 != speech_rate) {
                        config_info.speech_rate = speech_rate;
-
                        SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate change(%d)", config_info.speech_rate);
 
                        /* 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) {
-                                               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate changed callback : uid(%u)", temp_client->uid);
-                                               temp_client->speech_cb(config_info.speech_rate, temp_client->user_data);
-                                       }
-                               }
-
-                               iter = g_slist_next(iter);
-                       }
+                       invoke_speech_rate_changed_event(config_info.speech_rate);
                }
 
                if (-1 != pitch) {
                        config_info.pitch = pitch;
-
                        SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "pitch change(%d)", config_info.pitch);
 
                        /* 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->pitch_cb) {
-                                               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch changed callback : uid(%u)", temp_client->uid);
-                                               temp_client->pitch_cb(config_info.pitch, temp_client->user_data);
-                                       }
-                               }
-
-                               iter = g_slist_next(iter);
-                       }
+                       invoke_pitch_changed_event(config_info.pitch);
                }
 
                if (0.0 <= bg_volume_ratio) {
                        config_info.bg_volume_ratio = bg_volume_ratio;
-
                        SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio change(%lf)", config_info.bg_volume_ratio);
 
                        /* 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->bg_volume_ratio_cb) {
-                                               SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio changed callback : uid(%u)", temp_client->uid);
-                                               temp_client->bg_volume_ratio_cb(config_info.bg_volume_ratio, temp_client->user_data);
-                                       }
-                               }
-
-                               iter = g_slist_next(iter);
-                       }
-               }
-
-               if (NULL != engine) {
-                       free(engine);
-                       engine = NULL;
-               }
-               if (NULL != setting) {
-                       free(setting);
-                       setting = NULL;
-               }
-               if (NULL != lang) {
-                       free(lang);
-                       lang = NULL;
+                       invoke_bg_volume_ratio_changed_event(config_info.bg_volume_ratio);
                }
 
                if (0 != tts_parser_set_config_info(&config_info)){
@@ -639,27 +872,19 @@ static int set_voice_by_automation(int allowed_type_flag)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to save config");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_voice_changed_event(config_info.language, config_info.type, selected_language, selected_type, config_info.auto_voice);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client is not allowed to save configuration. Skip saving configuration file.");
        }
 
-       char *before_lang = (NULL != config_info.language ? strdup(config_info.language) : NULL);
-       int before_type = config_info.type;
-
        set_voice_into_config(&config_info, selected_language, selected_type);
 
        if (0 != tts_parser_set_config_info(&config_info)){
                SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to set configure information");
-               free(before_lang);
                return TTS_CONFIG_ERROR_OPERATION_FAILED;
        }
 
-       /* Call all callbacks of client*/
-       voice_changed_cb_parameter_s params = {before_lang, before_type, config_info.language,
-                       config_info.type, config_info.auto_voice};
-       g_slist_foreach(g_config_client_list, __invoke_voice_changed_cb, &params);
-       free(before_lang);
-
        return TTS_CONFIG_ERROR_NONE;
 }
 
@@ -929,9 +1154,7 @@ static Eina_Bool __tts_config_mgr_engine_config_inotify_event_callback(void* dat
                }
 
                /* Call all callbacks of client*/
-               engine_changed_cb_parameter_s params = {config_info.engine_id, config_info.setting,config_info.language,
-                               config_info.type, config_info.auto_voice, config_info.credential};
-               g_slist_foreach(g_config_client_list, __invoke_engine_changed_cb, &params);
+               invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
        } else {
                SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Undefined event");
        }
@@ -1235,6 +1458,8 @@ int tts_config_mgr_finalize(unsigned int uid, tts_config_client_type_e client_ty
        SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type : %d", client_type);
        g_client_type &= ~client_type;
 
+       delete_all_event_invokers();
+
        __tts_config_release_engine();
 
        tts_parser_unload_config();
@@ -1530,6 +1755,8 @@ int tts_config_mgr_set_engine(const char* engine)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, " Fail to save config");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
        }
@@ -1652,6 +1879,8 @@ int tts_config_mgr_set_voice(const char* language, int type)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save default voice");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_voice_changed_event(config_info.language, config_info.type, language, type, config_info.auto_voice);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
        }
@@ -1778,6 +2007,8 @@ int tts_config_mgr_set_speech_rate(int value)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save speech rate");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_speech_rate_changed_event(value);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
        }
@@ -1863,6 +2094,8 @@ int tts_config_mgr_set_pitch(int value)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save pitch");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_pitch_changed_event(value);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
        }
@@ -1910,6 +2143,8 @@ int tts_config_mgr_set_bg_volume_ratio(double value)
                        SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save bg volume ratio");
                        return TTS_CONFIG_ERROR_OPERATION_FAILED;
                }
+
+               invoke_bg_volume_ratio_changed_event(value);
        } else {
                SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
        }
@@ -1926,7 +2161,6 @@ int tts_config_mgr_set_bg_volume_ratio(double value)
                SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to set configure information");
                return TTS_CONFIG_ERROR_OPERATION_FAILED;
        }
-
        return TTS_CONFIG_ERROR_NONE;
 }