2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
17 #include <sys/types.h>
22 #include "tts_setting.h"
23 #include "tts_setting_dbus.h"
25 static bool g_is_daemon_started = false;
27 static int __check_setting_tts_daemon();
29 static tts_setting_state_e g_state = TTS_SETTING_STATE_NONE;
31 static tts_setting_initialized_cb g_initialized_cb;
32 static void* g_user_data;
36 /* API Implementation */
37 static Eina_Bool __tts_setting_initialized(void *data)
39 g_initialized_cb(g_state, g_reason, g_user_data);
44 static Eina_Bool __tts_setting_connect_daemon(void *data)
47 if (0 != tts_setting_dbus_request_hello()) {
48 if (false == g_is_daemon_started) {
49 g_is_daemon_started = true;
50 __check_setting_tts_daemon();
55 SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
57 /* do request initialize */
60 ret = tts_setting_dbus_request_initialize();
62 if (TTS_SETTING_ERROR_ENGINE_NOT_FOUND == ret) {
63 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
64 } else if (TTS_SETTING_ERROR_NONE != ret) {
65 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection : %d", ret);
67 /* success to connect tts-daemon */
68 g_state = TTS_SETTING_STATE_READY;
73 ecore_timer_add(0, __tts_setting_initialized, NULL);
75 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
76 SLOG(LOG_DEBUG, TAG_TTSC, " ");
81 int tts_setting_initialize()
83 SLOG(LOG_DEBUG, TAG_TTSC, "===== Initialize TTS Setting");
85 if (TTS_SETTING_STATE_READY == g_state) {
86 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] TTS Setting has already been initialized. \n");
87 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
88 SLOG(LOG_DEBUG, TAG_TTSC, " ");
89 return TTS_SETTING_ERROR_NONE;
92 if( 0 != tts_setting_dbus_open_connection() ) {
93 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open connection\n ");
94 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
95 SLOG(LOG_DEBUG, TAG_TTSC, " ");
96 return TTS_SETTING_ERROR_OPERATION_FAILED;
100 if (0 != tts_setting_dbus_request_hello()) {
101 __check_setting_tts_daemon();
108 ret = tts_setting_dbus_request_initialize();
110 if( TTS_SETTING_ERROR_ENGINE_NOT_FOUND == ret ) {
111 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
116 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Connection Time out");
117 ret = TTS_SETTING_ERROR_TIMED_OUT;
122 /* success to connect tts-daemon */
127 if (TTS_SETTING_ERROR_NONE == ret) {
128 g_state = TTS_SETTING_STATE_READY;
129 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Initialize");
132 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
133 SLOG(LOG_DEBUG, TAG_TTSC, " ");
138 int tts_setting_initialize_async(tts_setting_initialized_cb callback, void* user_data)
140 SLOG(LOG_DEBUG, TAG_TTSC, "===== Initialize TTS Setting");
142 if (TTS_SETTING_STATE_READY == g_state) {
143 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] TTS Setting has already been initialized. \n");
144 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
145 SLOG(LOG_DEBUG, TAG_TTSC, " ");
146 return TTS_SETTING_ERROR_NONE;
149 if( 0 != tts_setting_dbus_open_connection() ) {
150 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open connection\n ");
151 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
152 SLOG(LOG_DEBUG, TAG_TTSC, " ");
153 return TTS_SETTING_ERROR_OPERATION_FAILED;
156 g_initialized_cb = callback;
157 g_user_data = user_data;
159 ecore_timer_add(0, __tts_setting_connect_daemon, NULL);
161 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
162 SLOG(LOG_DEBUG, TAG_TTSC, " ");
164 return TTS_SETTING_ERROR_NONE;
168 int tts_setting_finalize()
170 SLOG(LOG_DEBUG, TAG_TTSC, "===== Finalize TTS Setting");
172 if (TTS_SETTING_STATE_NONE == g_state) {
173 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Not initialized");
174 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
175 SLOG(LOG_DEBUG, TAG_TTSC, " ");
176 return TTS_SETTING_ERROR_INVALID_STATE;
179 int ret = tts_setting_dbus_request_finalilze();
181 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
182 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
183 SLOG(LOG_DEBUG, TAG_TTSC, " ");
185 return TTS_SETTING_ERROR_OPERATION_FAILED;
188 if (0 != tts_setting_dbus_close_connection()) {
189 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection\n ");
191 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Finalize");
194 g_state = TTS_SETTING_STATE_NONE;
196 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
197 SLOG(LOG_DEBUG, TAG_TTSC, " ");
199 return TTS_SETTING_ERROR_NONE;
202 int tts_setting_foreach_supported_engines(tts_setting_supported_engine_cb callback, void* user_data)
204 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported engines");
206 if (TTS_SETTING_STATE_NONE == g_state) {
207 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
208 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
209 SLOG(LOG_DEBUG, TAG_TTSC, " ");
210 return TTS_SETTING_ERROR_INVALID_STATE;
213 if (NULL == callback) {
214 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Callback is NULL");
215 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
216 SLOG(LOG_DEBUG, TAG_TTSC, " ");
217 return TTS_SETTING_ERROR_INVALID_PARAMETER;
220 int ret = tts_setting_dbus_request_get_engine_list(callback, user_data);
222 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
224 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported engines");
227 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
228 SLOG(LOG_DEBUG, TAG_TTSC, " ");
233 int tts_setting_get_engine(char** engine_id)
235 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get current engine");
237 if (TTS_SETTING_STATE_NONE == g_state) {
238 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
239 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
240 SLOG(LOG_DEBUG, TAG_TTSC, " ");
241 return TTS_SETTING_ERROR_INVALID_STATE;
244 if (NULL == engine_id) {
245 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine id is NULL");
246 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
247 SLOG(LOG_DEBUG, TAG_TTSC, " ");
248 return TTS_SETTING_ERROR_INVALID_PARAMETER;
251 int ret = tts_setting_dbus_request_get_engine(engine_id);
253 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
255 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Get current engine");
258 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
259 SLOG(LOG_DEBUG, TAG_TTSC, " ");
264 int tts_setting_set_engine(const char* engine_id)
266 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set current engine");
268 if (TTS_SETTING_STATE_NONE == g_state) {
269 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
270 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
271 SLOG(LOG_DEBUG, TAG_TTSC, " ");
272 return TTS_SETTING_ERROR_INVALID_STATE;
275 if (NULL == engine_id) {
276 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine id is NULL");
277 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
278 SLOG(LOG_DEBUG, TAG_TTSC, " ");
279 return TTS_SETTING_ERROR_INVALID_PARAMETER;
282 int ret = tts_setting_dbus_request_set_engine(engine_id);
284 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
286 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set current engine");
289 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
290 SLOG(LOG_DEBUG, TAG_TTSC, " ");
295 int tts_setting_foreach_surpported_voices(tts_setting_supported_voice_cb callback, void* user_data)
297 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
299 if (TTS_SETTING_STATE_NONE == g_state) {
300 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
301 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
302 SLOG(LOG_DEBUG, TAG_TTSC, " ");
303 return TTS_SETTING_ERROR_INVALID_STATE;
306 if (NULL == callback) {
307 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
308 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
309 SLOG(LOG_DEBUG, TAG_TTSC, " ");
310 return TTS_SETTING_ERROR_INVALID_PARAMETER;
313 int ret = tts_setting_dbus_request_get_voice_list(callback, user_data);
316 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
318 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported voices");
321 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
322 SLOG(LOG_DEBUG, TAG_TTSC, " ");
327 int tts_setting_get_default_voice(char** language, tts_setting_voice_type_e* voice_type)
329 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
331 if (TTS_SETTING_STATE_NONE == g_state) {
332 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
333 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
334 SLOG(LOG_DEBUG, TAG_TTSC, " ");
335 return TTS_SETTING_ERROR_INVALID_STATE;
338 if (NULL == language || NULL == voice_type) {
339 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
340 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
341 SLOG(LOG_DEBUG, TAG_TTSC, " ");
342 return TTS_SETTING_ERROR_INVALID_PARAMETER;
345 int ret = tts_setting_dbus_request_get_default_voice(language, voice_type);
347 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
349 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported voices");
352 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
353 SLOG(LOG_DEBUG, TAG_TTSC, " ");
358 int tts_setting_set_default_voice(const char* language, tts_setting_voice_type_e voice_type)
360 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set default voice");
362 if (TTS_SETTING_STATE_NONE == g_state) {
363 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
364 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
365 SLOG(LOG_DEBUG, TAG_TTSC, " ");
366 return TTS_SETTING_ERROR_INVALID_STATE;
369 if (NULL == language) {
370 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
371 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
372 SLOG(LOG_DEBUG, TAG_TTSC, " ");
373 return TTS_SETTING_ERROR_INVALID_PARAMETER;
376 if (voice_type < TTS_SETTING_VOICE_TYPE_MALE || TTS_SETTING_VOICE_TYPE_USER3 < voice_type ) {
377 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid voice type");
378 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
379 SLOG(LOG_DEBUG, TAG_TTSC, " ");
380 return TTS_SETTING_ERROR_INVALID_PARAMETER;
383 int ret = tts_setting_dbus_request_set_default_voice(language, voice_type);
385 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
387 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default voice");
390 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
391 SLOG(LOG_DEBUG, TAG_TTSC, " ");
397 int tts_setting_get_default_speed(tts_setting_speed_e* speed)
399 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default speed");
401 if (TTS_SETTING_STATE_NONE == g_state) {
402 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
403 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
404 SLOG(LOG_DEBUG, TAG_TTSC, " ");
405 return TTS_SETTING_ERROR_INVALID_STATE;
409 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
410 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
411 SLOG(LOG_DEBUG, TAG_TTSC, " ");
412 return TTS_SETTING_ERROR_INVALID_PARAMETER;
418 int ret = tts_setting_dbus_request_get_default_speed(&temp);
420 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
423 *speed = (tts_setting_speed_e)temp;
424 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Get default speed : %d ", (int)*speed);
427 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
428 SLOG(LOG_DEBUG, TAG_TTSC, " ");
434 int tts_setting_set_default_speed(tts_setting_speed_e speed)
436 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set default speed");
438 if (TTS_SETTING_STATE_NONE == g_state) {
439 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
440 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
441 SLOG(LOG_DEBUG, TAG_TTSC, " ");
442 return TTS_SETTING_ERROR_INVALID_STATE;
445 if (speed < TTS_SETTING_SPEED_VERY_SLOW || TTS_SETTING_SPEED_VERY_FAST < speed) {
446 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid speed");
447 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
448 SLOG(LOG_DEBUG, TAG_TTSC, " ");
449 return TTS_SETTING_ERROR_INVALID_PARAMETER;
452 int ret = tts_setting_dbus_request_set_default_speed((int)speed);
454 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
456 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default speed");
459 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
460 SLOG(LOG_DEBUG, TAG_TTSC, " ");
465 int tts_setting_foreach_engine_settings(tts_setting_engine_setting_cb callback, void* user_data)
467 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach engine setting");
469 if (TTS_SETTING_STATE_NONE == g_state) {
470 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
471 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
472 SLOG(LOG_DEBUG, TAG_TTSC, " ");
473 return TTS_SETTING_ERROR_INVALID_STATE;
476 if (NULL == callback) {
477 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
478 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
479 SLOG(LOG_DEBUG, TAG_TTSC, " ");
480 return TTS_SETTING_ERROR_INVALID_PARAMETER;
483 int ret = tts_setting_dbus_request_get_engine_setting(callback, user_data);
485 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
487 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach engine setting");
490 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
491 SLOG(LOG_DEBUG, TAG_TTSC, " ");
496 int tts_setting_set_engine_setting(const char* key, const char* value)
498 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set engine setting");
500 if (TTS_SETTING_STATE_NONE == g_state) {
501 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
502 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
503 SLOG(LOG_DEBUG, TAG_TTSC, " ");
504 return TTS_SETTING_ERROR_INVALID_STATE;
507 if(NULL == key || NULL == value) {
508 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
509 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
510 SLOG(LOG_DEBUG, TAG_TTSC, " ");
511 return TTS_SETTING_ERROR_INVALID_PARAMETER;
514 int ret = tts_setting_dbus_request_set_engine_setting(key, value);
516 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
518 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach engine setting");
521 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
522 SLOG(LOG_DEBUG, TAG_TTSC, " ");
527 int __setting_get_cmd_line(char *file, char *buf)
532 fp = fopen(file, "r");
534 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
545 /* Functions for tts-daemon fork */
546 static bool __tts_setting_is_alive()
549 struct dirent *entry;
550 struct stat filestat;
556 dir = opendir("/proc");
558 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
562 while ((entry = readdir(dir)) != NULL) {
563 if (0 != lstat(entry->d_name, &filestat))
566 if (!S_ISDIR(filestat.st_mode))
569 pid = atoi(entry->d_name);
570 if (pid <= 0) continue;
572 sprintf(tempPath, "/proc/%d/cmdline", pid);
573 if (0 != __setting_get_cmd_line(tempPath, cmdLine)) {
577 if (0 == strncmp(cmdLine, "[tts-daemon]", strlen("[tts-daemon]")) ||
578 0 == strncmp(cmdLine, "tts-daemon", strlen("tts-daemon")) ||
579 0 == strncmp(cmdLine, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))) {
580 SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !! \n");
585 SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon !! \n");
592 static void __setting_my_sig_child(int signo, siginfo_t *info, void *data)
595 pid_t child_pid, child_pgid;
597 child_pgid = getpgid(info->si_pid);
598 SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d", info->si_pid, child_pgid);
600 while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
601 if(child_pid == child_pgid)
602 killpg(child_pgid, SIGKILL);
608 static int __check_setting_tts_daemon()
610 if( TRUE == __tts_setting_is_alive() )
613 /* fork-exec tts-daemom */
615 struct sigaction act, dummy;
617 act.sa_handler = NULL;
618 act.sa_sigaction = __setting_my_sig_child;
619 sigemptyset(&act.sa_mask);
620 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
622 if (sigaction(SIGCHLD, &act, &dummy) < 0) {
623 SLOG(LOG_ERROR, TAG_TTSC, "Cannot make a signal handler");
631 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create tts-daemon ");
636 for( i = 0 ; i < _NSIG ; i++ )
639 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);