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.
18 #include <sys/types.h>
22 #include "tts_client.h"
25 #define MAX_TEXT_COUNT 2000
27 static bool g_is_daemon_started = false;
29 static bool g_is_noti_daemon_started = false;
31 static bool g_is_sr_daemon_started = false;
33 static Ecore_Timer* g_connect_timer = NULL;
35 /* Function definition */
36 static int __tts_check_tts_daemon(tts_mode_e mode);
37 static Eina_Bool __tts_notify_state_changed(void *data);
38 static Eina_Bool __tts_notify_error(void *data);
40 int tts_create(tts_h* tts)
42 SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
46 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
47 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
48 SLOG(LOG_DEBUG, TAG_TTSC, " ");
49 return TTS_ERROR_INVALID_PARAMETER;
52 if (0 == tts_client_get_size()) {
53 if (0 != tts_dbus_open_connection()) {
54 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
55 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
56 SLOG(LOG_DEBUG, TAG_TTSC, " ");
57 return TTS_ERROR_OPERATION_FAILED;
61 if (0 != tts_client_new(tts)) {
62 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
63 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
64 SLOG(LOG_DEBUG, TAG_TTSC, " ");
65 return TTS_ERROR_OUT_OF_MEMORY;
68 g_is_daemon_started = false;
69 g_is_noti_daemon_started = false;
70 g_is_sr_daemon_started = false;
72 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
73 SLOG(LOG_DEBUG, TAG_TTSC, " ");
75 return TTS_ERROR_NONE;
78 int tts_destroy(tts_h tts)
80 SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
83 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
84 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
85 SLOG(LOG_DEBUG, TAG_TTSC, " ");
86 return TTS_ERROR_INVALID_PARAMETER;
89 tts_client_s* client = tts_client_get(tts);
93 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
94 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
95 SLOG(LOG_DEBUG, TAG_TTSC, " ");
96 return TTS_ERROR_INVALID_PARAMETER;
99 /* check used callback */
100 if (0 != tts_client_get_use_callback(client)) {
101 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot destroy in Callback function");
102 return TTS_ERROR_OPERATION_FAILED;
108 switch (client->current_state) {
109 case TTS_STATE_PAUSED:
110 case TTS_STATE_PLAYING:
111 case TTS_STATE_READY:
112 /* Request Finalize */
113 ret = tts_dbus_request_finalize(client->uid);
115 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
118 if (TTS_MODE_SCREEN_READER == client->mode)
119 g_is_sr_daemon_started = false;
120 else if (TTS_MODE_NOTIFICATION == client->mode)
121 g_is_noti_daemon_started = false;
123 g_is_daemon_started = false;
125 client->before_state = client->current_state;
126 client->current_state = TTS_STATE_CREATED;
128 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
130 /* Close file message connection */
131 if (0 == tts_client_get_connected_client_count()) {
132 SLOG(LOG_DEBUG, TAG_TTSC, "Close file msg connection");
133 ret = tts_file_msg_close_connection();
135 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to close file message connection");
138 case TTS_STATE_CREATED:
139 if (NULL != g_connect_timer) {
140 SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
141 ecore_timer_del(g_connect_timer);
144 tts_client_destroy(tts);
148 if (0 == tts_client_get_size()) {
149 if (0 != tts_dbus_close_connection()) {
150 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
154 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
155 SLOG(LOG_DEBUG, TAG_TTSC, " ");
157 return TTS_ERROR_NONE;
160 int tts_set_mode(tts_h tts, tts_mode_e mode)
162 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set TTS mode");
164 tts_client_s* client = tts_client_get(tts);
167 if (NULL == client) {
168 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
169 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
170 SLOG(LOG_DEBUG, TAG_TTSC, " ");
171 return TTS_ERROR_INVALID_PARAMETER;
175 if (client->current_state != TTS_STATE_CREATED) {
176 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
177 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
178 SLOG(LOG_DEBUG, TAG_TTSC, " ");
179 return TTS_ERROR_INVALID_STATE;
182 if (TTS_MODE_DEFAULT <= mode && mode <= TTS_MODE_SCREEN_READER) {
185 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid : %d", mode);
186 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
187 SLOG(LOG_DEBUG, TAG_TTSC, " ");
188 return TTS_ERROR_INVALID_PARAMETER;
191 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
192 SLOG(LOG_DEBUG, TAG_TTSC, " ");
194 return TTS_ERROR_NONE;
197 int tts_get_mode(tts_h tts, tts_mode_e* mode)
199 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get TTS mode");
201 tts_client_s* client = tts_client_get(tts);
204 if (NULL == client) {
205 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
206 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
207 SLOG(LOG_DEBUG, TAG_TTSC, " ");
208 return TTS_ERROR_INVALID_PARAMETER;
212 if (client->current_state != TTS_STATE_CREATED) {
213 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
214 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
215 SLOG(LOG_DEBUG, TAG_TTSC, " ");
216 return TTS_ERROR_INVALID_STATE;
220 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter(mode) is NULL");
221 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
222 SLOG(LOG_DEBUG, TAG_TTSC, " ");
223 return TTS_ERROR_INVALID_PARAMETER;
226 *mode = client->mode;
228 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
229 SLOG(LOG_DEBUG, TAG_TTSC, " ");
231 return TTS_ERROR_NONE;
234 static Eina_Bool __tts_connect_daemon(void *data)
236 tts_h tts = (tts_h)data;
238 tts_client_s* client = tts_client_get(tts);
241 if (NULL == client) {
242 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
247 if (0 != tts_dbus_request_hello(client->uid)) {
248 if (TTS_MODE_SCREEN_READER == client->mode) {
249 if (false == g_is_sr_daemon_started) {
250 g_is_sr_daemon_started = true;
251 __tts_check_tts_daemon(client->mode);
253 } else if (TTS_MODE_NOTIFICATION == client->mode) {
254 if (false == g_is_noti_daemon_started) {
255 g_is_noti_daemon_started = true;
256 __tts_check_tts_daemon(client->mode);
259 if (false == g_is_daemon_started) {
260 g_is_daemon_started = true;
261 __tts_check_tts_daemon(client->mode);
268 SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
270 /* do request initialize */
273 ret = tts_dbus_request_initialize(client->uid);
275 if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
276 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
278 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
281 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
284 } else if (TTS_ERROR_NONE != ret) {
285 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
287 client->reason = TTS_ERROR_TIMED_OUT;
290 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
293 /* success to connect tts-daemon */
296 if (0 == tts_client_get_connected_client_count()) {
297 SLOG(LOG_DEBUG, TAG_TTSC, "Open file msg connection");
298 ret = tts_file_msg_open_connection();
300 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open file message connection");
301 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
306 client->before_state = client->current_state;
307 client->current_state = TTS_STATE_READY;
309 ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
311 g_connect_timer = NULL;
313 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
315 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
316 SLOG(LOG_DEBUG, TAG_TTSC, " ");
321 int tts_prepare(tts_h tts)
323 SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
325 tts_client_s* client = tts_client_get(tts);
328 if (NULL == client) {
329 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
330 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
331 SLOG(LOG_DEBUG, TAG_TTSC, " ");
332 return TTS_ERROR_INVALID_PARAMETER;
336 if (client->current_state != TTS_STATE_CREATED) {
337 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
338 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
339 SLOG(LOG_DEBUG, TAG_TTSC, " ");
340 return TTS_ERROR_INVALID_STATE;
343 g_connect_timer = ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
345 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
346 SLOG(LOG_DEBUG, TAG_TTSC, " ");
348 return TTS_ERROR_NONE;
351 int tts_unprepare(tts_h tts)
353 SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
355 tts_client_s* client = tts_client_get(tts);
358 if (NULL == client) {
359 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
360 return TTS_ERROR_INVALID_PARAMETER;
364 if (client->current_state != TTS_STATE_READY) {
365 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'");
366 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
367 SLOG(LOG_DEBUG, TAG_TTSC, " ");
368 return TTS_ERROR_INVALID_STATE;
373 ret = tts_dbus_request_finalize(client->uid);
375 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
378 if (TTS_MODE_SCREEN_READER == client->mode)
379 g_is_sr_daemon_started = false;
380 else if (TTS_MODE_NOTIFICATION == client->mode)
381 g_is_noti_daemon_started = false;
383 g_is_daemon_started = false;
385 client->before_state = client->current_state;
386 client->current_state = TTS_STATE_CREATED;
388 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
390 /* Close file message connection */
391 if (0 == tts_client_get_connected_client_count()) {
392 SLOG(LOG_DEBUG, TAG_TTSC, "Close file msg connection");
393 ret = tts_file_msg_close_connection();
395 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to close file message connection");
398 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
399 SLOG(LOG_DEBUG, TAG_TTSC, " ");
401 return TTS_ERROR_NONE;
404 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
406 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
408 if (NULL == tts || NULL == callback) {
409 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
410 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
411 SLOG(LOG_DEBUG, TAG_TTSC, " ");
412 return TTS_ERROR_INVALID_PARAMETER;
415 tts_client_s* client = tts_client_get(tts);
418 if (NULL == client) {
419 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
420 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
421 SLOG(LOG_DEBUG, TAG_TTSC, " ");
422 return TTS_ERROR_INVALID_PARAMETER;
425 if (TTS_STATE_READY != client->current_state) {
426 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");
427 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
428 SLOG(LOG_DEBUG, TAG_TTSC, " ");
429 return TTS_ERROR_INVALID_STATE;
433 ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
435 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
438 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
439 SLOG(LOG_DEBUG, TAG_TTSC, " ");
444 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
446 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
449 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
450 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
451 SLOG(LOG_DEBUG, TAG_TTSC, " ");
452 return TTS_ERROR_INVALID_PARAMETER;
455 tts_client_s* client = tts_client_get(tts);
457 if (NULL == client) {
458 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
459 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
460 SLOG(LOG_DEBUG, TAG_TTSC, " ");
461 return TTS_ERROR_INVALID_PARAMETER;
464 if (TTS_STATE_READY != client->current_state) {
465 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
466 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
467 SLOG(LOG_DEBUG, TAG_TTSC, " ");
468 return TTS_ERROR_INVALID_STATE;
471 /* Request call remote method */
473 ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
476 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
479 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
480 SLOG(LOG_DEBUG, TAG_TTSC, " ");
485 int tts_get_max_text_count(tts_h tts, int* count)
487 if (NULL == tts || NULL == count) {
488 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
489 return TTS_ERROR_INVALID_PARAMETER;
492 tts_client_s* client = tts_client_get(tts);
494 if (NULL == client) {
495 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
496 return TTS_ERROR_INVALID_PARAMETER;
499 if (TTS_STATE_READY != client->current_state) {
500 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'.");
501 return TTS_ERROR_INVALID_STATE;
504 *count = MAX_TEXT_COUNT;
506 SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
507 return TTS_ERROR_NONE;
510 int tts_get_state(tts_h tts, tts_state_e* state)
512 if (NULL == tts || NULL == state) {
513 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
514 return TTS_ERROR_INVALID_PARAMETER;
517 tts_client_s* client = tts_client_get(tts);
519 if (NULL == client) {
520 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
521 return TTS_ERROR_INVALID_PARAMETER;
524 *state = client->current_state;
527 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'"); break;
528 case TTS_STATE_READY: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'"); break;
529 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'"); break;
530 case TTS_STATE_PAUSED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'"); break;
533 return TTS_ERROR_NONE;
536 int tts_add_text(tts_h tts, const char* text, const char* language, tts_voice_type_e voice_type, tts_speed_e speed, int* utt_id)
538 SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
540 if (NULL == tts || NULL == utt_id) {
541 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
542 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
543 SLOG(LOG_DEBUG, TAG_TTSC, " ");
544 return TTS_ERROR_INVALID_PARAMETER;
547 tts_client_s* client = tts_client_get(tts);
549 if (NULL == client) {
550 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
551 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
552 SLOG(LOG_DEBUG, TAG_TTSC, " ");
553 return TTS_ERROR_INVALID_PARAMETER;
556 if (TTS_STATE_CREATED == client->current_state) {
557 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
558 return TTS_ERROR_INVALID_STATE;
561 if (MAX_TEXT_COUNT < strlen(text)) {
562 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is too big.");
563 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
564 SLOG(LOG_DEBUG, TAG_TTSC, " ");
565 return TTS_ERROR_INVALID_PARAMETER;
568 /* change default language value */
571 if (NULL == language)
572 temp = strdup("default");
574 temp = strdup(language);
576 client->current_utt_id ++;
577 if (client->current_utt_id == 10000) {
578 client->current_utt_id = 1;
583 ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
585 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
587 *utt_id = client->current_utt_id;
593 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
594 SLOG(LOG_DEBUG, TAG_TTSC, " ");
599 int tts_play(tts_h tts)
601 SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
604 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
605 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
606 SLOG(LOG_DEBUG, TAG_TTSC, " ");
607 return TTS_ERROR_INVALID_PARAMETER;
610 tts_client_s* client = tts_client_get(tts);
612 if (NULL == client) {
613 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
614 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
615 SLOG(LOG_DEBUG, TAG_TTSC, " ");
616 return TTS_ERROR_INVALID_PARAMETER;
619 if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
620 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
621 return TTS_ERROR_INVALID_STATE;
625 ret = tts_dbus_request_play(client->uid);
627 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
628 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
629 SLOG(LOG_DEBUG, TAG_TTSC, " ");
633 client->before_state = client->current_state;
634 client->current_state = TTS_STATE_PLAYING;
636 if (NULL != client->state_changed_cb) {
637 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
639 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
642 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
643 SLOG(LOG_DEBUG, TAG_TTSC, " ");
645 return TTS_ERROR_NONE;
649 int tts_stop(tts_h tts)
651 SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
654 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
655 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
656 SLOG(LOG_DEBUG, TAG_TTSC, " ");
657 return TTS_ERROR_INVALID_PARAMETER;
660 tts_client_s* client = tts_client_get(tts);
662 if (NULL == client) {
663 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
664 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
665 SLOG(LOG_DEBUG, TAG_TTSC, " ");
666 return TTS_ERROR_INVALID_PARAMETER;
669 if (TTS_STATE_CREATED == client->current_state) {
670 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
671 return TTS_ERROR_INVALID_STATE;
675 ret = tts_dbus_request_stop(client->uid);
677 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
678 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
679 SLOG(LOG_DEBUG, TAG_TTSC, " ");
683 client->before_state = client->current_state;
684 client->current_state = TTS_STATE_READY;
686 if (NULL != client->state_changed_cb) {
687 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
689 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
692 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
693 SLOG(LOG_DEBUG, TAG_TTSC, " ");
695 return TTS_ERROR_NONE;
699 int tts_pause(tts_h tts)
701 SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
704 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
705 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
706 SLOG(LOG_DEBUG, TAG_TTSC, " ");
707 return TTS_ERROR_INVALID_PARAMETER;
710 tts_client_s* client = tts_client_get(tts);
712 if (NULL == client) {
713 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
714 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
715 SLOG(LOG_DEBUG, TAG_TTSC, " ");
716 return TTS_ERROR_INVALID_PARAMETER;
719 if (TTS_STATE_PLAYING != client->current_state) {
720 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
721 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
722 SLOG(LOG_DEBUG, TAG_TTSC, " ");
723 return TTS_ERROR_INVALID_STATE;
727 ret = tts_dbus_request_pause(client->uid);
729 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
730 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
731 SLOG(LOG_DEBUG, TAG_TTSC, " ");
735 client->before_state = client->current_state;
736 client->current_state = TTS_STATE_PAUSED;
738 if (NULL != client->state_changed_cb) {
739 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
741 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
744 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
745 SLOG(LOG_DEBUG, TAG_TTSC, " ");
747 return TTS_ERROR_NONE;
750 static Eina_Bool __tts_notify_error(void *data)
752 tts_h tts = (tts_h)data;
754 tts_client_s* client = tts_client_get(tts);
757 if (NULL == client) {
758 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
762 if (NULL != client->error_cb) {
763 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
764 tts_client_use_callback(client);
765 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
766 tts_client_not_use_callback(client);
768 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
774 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
776 tts_client_s* client = tts_client_get_by_uid(uid);
778 if (NULL == client) {
779 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
780 return TTS_ERROR_INVALID_PARAMETER;
783 client->utt_id = utt_id;
784 client->reason = reason;
786 /* call callback function */
787 if (NULL != client->error_cb) {
788 ecore_timer_add(0, __tts_notify_error, client->tts);
790 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
796 static Eina_Bool __tts_notify_state_changed(void *data)
798 tts_h tts = (tts_h)data;
800 tts_client_s* client = tts_client_get(tts);
803 if (NULL == client) {
804 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
808 if (NULL != client->state_changed_cb) {
809 tts_client_use_callback(client);
810 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
811 tts_client_not_use_callback(client);
812 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
814 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
820 int __tts_cb_set_state(int uid, int state)
822 tts_client_s* client = tts_client_get_by_uid(uid);
823 if( NULL == client ) {
824 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
828 tts_state_e state_from_daemon = (tts_state_e)state;
830 if (client->current_state == state_from_daemon) {
831 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
835 if (NULL != client->state_changed_cb) {
836 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
838 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
841 client->before_state = client->current_state;
842 client->current_state = state_from_daemon;
847 static Eina_Bool __tts_notify_utt_started(void *data)
849 tts_h tts = (tts_h)data;
851 tts_client_s* client = tts_client_get(tts);
854 if (NULL == client) {
855 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
859 if (NULL != client->utt_started_cb) {
860 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
861 tts_client_use_callback(client);
862 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
863 tts_client_not_use_callback(client);
865 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
871 int __tts_cb_utt_started(int uid, int utt_id)
873 tts_client_s* client = tts_client_get_by_uid(uid);
875 if (NULL == client) {
876 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
877 return TTS_ERROR_INVALID_PARAMETER;
880 SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
882 client->utt_id = utt_id;
884 /* call callback function */
885 if (NULL != client->utt_started_cb) {
886 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
888 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
894 static Eina_Bool __tts_notify_utt_completed(void *data)
896 tts_h tts = (tts_h)data;
898 tts_client_s* client = tts_client_get(tts);
901 if (NULL == client) {
902 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
906 if (NULL != client->utt_completeted_cb) {
907 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
908 tts_client_use_callback(client);
909 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
910 tts_client_not_use_callback(client);
912 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
918 int __tts_cb_utt_completed(int uid, int utt_id)
920 tts_client_s* client = tts_client_get_by_uid(uid);
922 if (NULL == client) {
923 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
924 return TTS_ERROR_INVALID_PARAMETER;
927 SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
929 client->utt_id = utt_id;
931 /* call callback function */
932 if (NULL != client->utt_completeted_cb) {
933 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
935 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
941 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
943 if (NULL == tts || NULL == callback) {
944 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
945 return TTS_ERROR_INVALID_PARAMETER;
948 tts_client_s* client = tts_client_get(tts);
950 if (NULL == client) {
951 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
952 return TTS_ERROR_INVALID_PARAMETER;
955 if (TTS_STATE_CREATED != client->current_state) {
956 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'.");
957 return TTS_ERROR_INVALID_STATE;
960 client->state_changed_cb = callback;
961 client->state_changed_user_data = user_data;
963 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
968 int tts_unset_state_changed_cb(tts_h tts)
971 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
972 return TTS_ERROR_INVALID_PARAMETER;
975 tts_client_s* client = tts_client_get(tts);
977 if (NULL == client) {
978 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
979 return TTS_ERROR_INVALID_PARAMETER;
982 if (TTS_STATE_CREATED != client->current_state) {
983 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'.");
984 return TTS_ERROR_INVALID_STATE;
987 client->state_changed_cb = NULL;
988 client->state_changed_user_data = NULL;
990 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
995 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
997 if (NULL == tts || NULL == callback) {
998 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
999 return TTS_ERROR_INVALID_PARAMETER;
1002 tts_client_s* client = tts_client_get(tts);
1004 if (NULL == client) {
1005 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
1006 return TTS_ERROR_INVALID_PARAMETER;
1009 if (TTS_STATE_CREATED != client->current_state) {
1010 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'.");
1011 return TTS_ERROR_INVALID_STATE;
1014 client->utt_started_cb = callback;
1015 client->utt_started_user_data = user_data;
1017 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
1022 int tts_unset_utterance_started_cb(tts_h tts)
1025 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
1026 return TTS_ERROR_INVALID_PARAMETER;
1029 tts_client_s* client = tts_client_get(tts);
1031 if (NULL == client) {
1032 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
1033 return TTS_ERROR_INVALID_PARAMETER;
1036 if (TTS_STATE_CREATED != client->current_state) {
1037 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'.");
1038 return TTS_ERROR_INVALID_STATE;
1041 client->utt_started_cb = NULL;
1042 client->utt_started_user_data = NULL;
1044 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
1049 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
1051 if (NULL == tts || NULL == callback) {
1052 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
1053 return TTS_ERROR_INVALID_PARAMETER;
1056 tts_client_s* client = tts_client_get(tts);
1058 if (NULL == client) {
1059 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
1060 return TTS_ERROR_INVALID_PARAMETER;
1063 if (TTS_STATE_CREATED != client->current_state) {
1064 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'.");
1065 return TTS_ERROR_INVALID_STATE;
1068 client->utt_completeted_cb = callback;
1069 client->utt_completed_user_data = user_data;
1071 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
1076 int tts_unset_utterance_completed_cb(tts_h tts)
1079 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
1080 return TTS_ERROR_INVALID_PARAMETER;
1083 tts_client_s* client = tts_client_get(tts);
1085 if (NULL == client) {
1086 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
1087 return TTS_ERROR_INVALID_PARAMETER;
1090 if (TTS_STATE_CREATED != client->current_state) {
1091 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'.");
1092 return TTS_ERROR_INVALID_STATE;
1095 client->utt_completeted_cb = NULL;
1096 client->utt_completed_user_data = NULL;
1098 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
1102 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
1104 if (NULL == tts || NULL == callback) {
1105 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
1106 return TTS_ERROR_INVALID_PARAMETER;
1109 tts_client_s* client = tts_client_get(tts);
1111 if (NULL == client) {
1112 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
1113 return TTS_ERROR_INVALID_PARAMETER;
1116 if (TTS_STATE_CREATED != client->current_state) {
1117 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'.");
1118 return TTS_ERROR_INVALID_STATE;
1121 client->error_cb = callback;
1122 client->error_user_data = user_data;
1124 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
1129 int tts_unset_error_cb(tts_h tts)
1132 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
1133 return TTS_ERROR_INVALID_PARAMETER;
1136 tts_client_s* client = tts_client_get(tts);
1138 if (NULL == client) {
1139 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
1140 return TTS_ERROR_INVALID_PARAMETER;
1143 if (TTS_STATE_CREATED != client->current_state) {
1144 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'.");
1145 return TTS_ERROR_INVALID_STATE;
1148 client->error_cb = NULL;
1149 client->error_user_data = NULL;
1151 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
1156 static int __get_cmd_line(char *file, char *buf)
1160 fp = fopen(file, "r");
1162 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
1166 memset(buf, 0, 256);
1167 if (NULL == fgets(buf, 256, fp)) {
1168 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to fget command line");
1177 static bool __tts_is_alive(char* daemon_path)
1180 struct dirent *entry;
1181 struct stat filestat;
1184 char cmdLine[256] = {'\0',};
1185 char tempPath[256] = {'\0',};
1187 dir = opendir("/proc");
1189 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
1193 while ((entry = readdir(dir)) != NULL) {
1194 if (0 != lstat(entry->d_name, &filestat)) {
1198 if (!S_ISDIR(filestat.st_mode)) {
1202 pid = atoi(entry->d_name);
1203 if (pid <= 0) continue;
1205 sprintf(tempPath, "/proc/%d/cmdline", pid);
1206 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1210 if (0 == strncmp(cmdLine, daemon_path, strlen(daemon_path))) {
1211 SLOG(LOG_DEBUG, TAG_TTSC, "%s is ALIVE !!", daemon_path);
1217 SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO %s !!", daemon_path);
1223 static int __tts_check_tts_daemon(tts_mode_e mode)
1225 char daemon_path[64] = {'\0',};
1228 if (TTS_MODE_DEFAULT == mode) {
1229 strcpy(daemon_path, "/usr/bin/tts-daemon");
1230 } else if (TTS_MODE_NOTIFICATION == mode) {
1231 strcpy(daemon_path, "/usr/bin/tts-daemon-noti");
1232 } else if (TTS_MODE_SCREEN_READER == mode) {
1233 strcpy(daemon_path, "/usr/bin/tts-daemon-sr");
1235 SLOG(LOG_ERROR, TAG_TTSC, "mode is not valid");
1239 if (TRUE == __tts_is_alive(daemon_path)) {
1243 /* fork-exec daemom */
1248 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create daemon");
1253 for (i = 0;i < _NSIG;i++)
1256 execl(daemon_path, daemon_path, NULL);