+ tts_h tts = (tts_h)data;
+
+ tts_client_s* client = tts_client_get(tts);
+ if (NULL == client) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] A handle is not valid");
+ return EINA_FALSE;
+ }
+
+ if (TTS_STATE_READY != client->current_state) {
+ usleep(10000);
+ return EINA_TRUE;
+ }
+
+ int ret = tts_unprepare(tts);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
+ }
+ ret = tts_prepare(tts);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
+ }
+
+ return EINA_FALSE;
+}
+
+void _tts_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, int voice_type, bool auto_voice, bool need_credential, void* user_data)
+{
+ tts_h tts = (tts_h)user_data;
+
+ tts_client_s* client = tts_client_get(tts);
+ if (NULL == client) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] A handle is not valid");
+ return;
+ }
+
+ if (NULL != engine_id) SLOG(LOG_DEBUG, TAG_TTSC, "Engine id(%s)", engine_id);
+ if (NULL != setting) SLOG(LOG_DEBUG, TAG_TTSC, "Engine setting(%s)", setting);
+ if (NULL != language) SLOG(LOG_DEBUG, TAG_TTSC, "Language(%s)", language);
+ SLOG(LOG_DEBUG, TAG_TTSC, "Voice type(%d), Auto voice(%s), Credential(%s)", voice_type, auto_voice ? "on" : "off", need_credential ? "need" : "no need");
+
+ /* When the default engine is changed, please unload the old engine and load the new one. */
+ int ret = -1;
+
+ if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_PAUSED == client->current_state) {
+ ret = tts_stop(tts);
+ if (0 != ret) {
+ SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] TTS client stopping...");
+ }
+
+ ecore_idler_add(__reconnect_by_engine_changed, (void*)tts);
+ } else if (TTS_STATE_READY == client->current_state) {
+ ret = tts_unprepare(tts);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to unprepare for setting a new engine... (%d)", ret);
+ }
+ ret = tts_prepare(tts);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
+ }
+ }
+
+ /* call callback function */
+ if (NULL != client->engine_changed_cb) {
+ client->engine_changed_cb(tts, engine_id, language, voice_type, need_credential, client->engine_changed_user_data);
+ } else {
+ SLOG(LOG_WARN, TAG_TTSC, "No registered callback function for changed engine");
+ }
+ return;
+}
+//LCOV_EXCL_STOP
+
+void __tts_unset_all_callbacks(tts_h tts)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ unset all callbacks");
+
+ tts_unset_state_changed_cb(tts);
+ tts_unset_utterance_started_cb(tts);
+ tts_unset_utterance_completed_cb(tts);
+ tts_unset_error_cb(tts);
+ tts_unset_default_voice_changed_cb(tts);
+ tts_unset_engine_changed_cb(tts);
+
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+}
+
+static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
+
+ if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
+ SLOG(LOG_DEBUG, TAG_TTSC, "[WARN] this is not tts engine");
+ return 0;
+ } else {
+ if (key && 0 == strncmp(key, "start", strlen(key))) {
+ if (val && (0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] start to install.");
+ g_engine_update_status = 1;
+ }
+ } else if (key && 0 == strncmp(key, "end", strlen(key))) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish to install");
+ g_engine_update_status = 0;
+ }
+ }
+
+ return 0;
+}
+
+static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] create pkgmgr thread");
+
+ pthread_mutex_lock(&g_pkgmgr_mutex);
+
+ while (!g_pkgmgr) {
+ g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
+ if (NULL == g_pkgmgr) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
+ } else {
+ if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ continue;
+ } else {
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Succeed to register pkgmgr cb");
+ }