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 1000
27 static bool g_is_daemon_started = false;
29 /* Function definition */
30 static int __tts_check_tts_daemon();
31 static Eina_Bool __tts_notify_state_changed(void *data);
32 static Eina_Bool __tts_notify_error(void *data);
34 int tts_create(tts_h* tts)
36 SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
40 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
41 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
42 SLOG(LOG_DEBUG, TAG_TTSC, " ");
43 return TTS_ERROR_INVALID_PARAMETER;
46 if (0 == tts_client_get_size()) {
47 if (0 != tts_dbus_open_connection()) {
48 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
49 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
50 SLOG(LOG_DEBUG, TAG_TTSC, " ");
51 return TTS_ERROR_OPERATION_FAILED;
55 if (0 != tts_client_new(tts)) {
56 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
57 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
58 SLOG(LOG_DEBUG, TAG_TTSC, " ");
59 return TTS_ERROR_OUT_OF_MEMORY;
62 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
63 SLOG(LOG_DEBUG, TAG_TTSC, " ");
65 return TTS_ERROR_NONE;
68 int tts_destroy(tts_h tts)
70 SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
73 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
74 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
75 SLOG(LOG_DEBUG, TAG_TTSC, " ");
76 return TTS_ERROR_INVALID_PARAMETER;
79 tts_client_s* client = tts_client_get(tts);
83 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
84 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
85 SLOG(LOG_DEBUG, TAG_TTSC, " ");
86 return TTS_ERROR_INVALID_PARAMETER;
92 switch (client->current_state) {
93 case TTS_STATE_PAUSED:
94 case TTS_STATE_PLAYING:
96 /* Request Finalize */
97 ret = tts_dbus_request_finalize(client->uid);
99 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize");
101 case TTS_STATE_CREATED:
103 tts_client_destroy(tts);
107 if (0 == tts_client_get_size()) {
108 if (0 != tts_dbus_close_connection()) {
109 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
113 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
114 SLOG(LOG_DEBUG, TAG_TTSC, " ");
116 return TTS_ERROR_NONE;
119 static Eina_Bool __tts_connect_daemon(void *data)
121 SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
123 tts_h tts = (tts_h)data;
125 tts_client_s* client = tts_client_get(tts);
128 if (NULL == client) {
129 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
130 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
131 SLOG(LOG_DEBUG, TAG_TTSC, " ");
136 if (0 != tts_dbus_request_hello()) {
137 if (false == g_is_daemon_started) {
138 g_is_daemon_started = true;
139 __tts_check_tts_daemon();
144 /* do request initialize */
147 ret = tts_dbus_request_initialize(client->uid);
149 if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
150 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
152 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
155 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
158 } else if (TTS_ERROR_NONE != ret) {
159 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
161 client->reason = TTS_ERROR_TIMED_OUT;
164 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
167 /* success to connect tts-daemon */
170 client->before_state = client->current_state;
171 client->current_state = TTS_STATE_READY;
173 ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
175 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
177 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
178 SLOG(LOG_DEBUG, TAG_TTSC, " ");
184 int tts_prepare(tts_h tts)
186 SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
188 tts_client_s* client = tts_client_get(tts);
191 if (NULL == client) {
192 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
193 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
194 SLOG(LOG_DEBUG, TAG_TTSC, " ");
195 return TTS_ERROR_INVALID_PARAMETER;
199 if (client->current_state != TTS_STATE_CREATED) {
200 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
201 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
202 SLOG(LOG_DEBUG, TAG_TTSC, " ");
203 return TTS_ERROR_INVALID_STATE;
206 ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
208 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
209 SLOG(LOG_DEBUG, TAG_TTSC, " ");
211 return TTS_ERROR_NONE;
214 int tts_unprepare(tts_h tts)
216 SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
218 tts_client_s* client = tts_client_get(tts);
221 if (NULL == client) {
222 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
223 return TTS_ERROR_INVALID_PARAMETER;
227 if (client->current_state != TTS_STATE_READY) {
228 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'");
229 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
230 SLOG(LOG_DEBUG, TAG_TTSC, " ");
231 return TTS_ERROR_INVALID_STATE;
234 int ret = tts_dbus_request_finalize(client->uid);
236 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
239 client->before_state = client->current_state;
240 client->current_state = TTS_STATE_CREATED;
242 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
244 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
245 SLOG(LOG_DEBUG, TAG_TTSC, " ");
247 return TTS_ERROR_NONE;
250 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
252 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
254 if (NULL == tts || NULL == callback) {
255 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
256 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
257 SLOG(LOG_DEBUG, TAG_TTSC, " ");
258 return TTS_ERROR_INVALID_PARAMETER;
261 tts_client_s* client = tts_client_get(tts);
264 if (NULL == client) {
265 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
266 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
267 SLOG(LOG_DEBUG, TAG_TTSC, " ");
268 return TTS_ERROR_INVALID_PARAMETER;
271 if (TTS_STATE_READY != client->current_state) {
272 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");
273 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
274 SLOG(LOG_DEBUG, TAG_TTSC, " ");
275 return TTS_ERROR_INVALID_STATE;
279 ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
281 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
284 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
285 SLOG(LOG_DEBUG, TAG_TTSC, " ");
290 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
292 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
295 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
296 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
297 SLOG(LOG_DEBUG, TAG_TTSC, " ");
298 return TTS_ERROR_INVALID_PARAMETER;
301 tts_client_s* client = tts_client_get(tts);
303 if (NULL == client) {
304 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
305 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
306 SLOG(LOG_DEBUG, TAG_TTSC, " ");
307 return TTS_ERROR_INVALID_PARAMETER;
310 if (TTS_STATE_READY != client->current_state) {
311 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
312 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
313 SLOG(LOG_DEBUG, TAG_TTSC, " ");
314 return TTS_ERROR_INVALID_STATE;
317 /* Request call remote method */
319 ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
322 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
325 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
326 SLOG(LOG_DEBUG, TAG_TTSC, " ");
331 int tts_get_max_text_count(tts_h tts, int* count)
333 if (NULL == tts || NULL == count) {
334 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
335 return TTS_ERROR_INVALID_PARAMETER;
338 tts_client_s* client = tts_client_get(tts);
340 if (NULL == client) {
341 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
342 return TTS_ERROR_INVALID_PARAMETER;
345 if (TTS_STATE_READY != client->current_state) {
346 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'.");
347 return TTS_ERROR_INVALID_STATE;
350 *count = MAX_TEXT_COUNT;
352 SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
353 return TTS_ERROR_NONE;
356 int tts_get_state(tts_h tts, tts_state_e* state)
358 if (NULL == tts || NULL == state) {
359 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
360 return TTS_ERROR_INVALID_PARAMETER;
363 tts_client_s* client = tts_client_get(tts);
365 if (NULL == client) {
366 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
367 return TTS_ERROR_INVALID_PARAMETER;
370 *state = client->current_state;
373 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'"); break;
374 case TTS_STATE_READY: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'"); break;
375 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'"); break;
376 case TTS_STATE_PAUSED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'"); break;
379 return TTS_ERROR_NONE;
382 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)
384 SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
386 if (NULL == tts || NULL == utt_id) {
387 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
388 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
389 SLOG(LOG_DEBUG, TAG_TTSC, " ");
390 return TTS_ERROR_INVALID_PARAMETER;
393 tts_client_s* client = tts_client_get(tts);
395 if (NULL == client) {
396 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
397 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
398 SLOG(LOG_DEBUG, TAG_TTSC, " ");
399 return TTS_ERROR_INVALID_PARAMETER;
402 if (TTS_STATE_CREATED == client->current_state) {
403 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
404 return TTS_ERROR_INVALID_STATE;
407 /* change default language value */
410 if (NULL == language)
411 temp = strdup("default");
413 temp = strdup(language);
415 client->current_utt_id ++;
416 if (client->current_utt_id == 10000) {
417 client->current_utt_id = 1;
422 ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
424 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
427 *utt_id = client->current_utt_id;
432 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
433 SLOG(LOG_DEBUG, TAG_TTSC, " ");
438 int tts_play(tts_h tts)
440 SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
443 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
444 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
445 SLOG(LOG_DEBUG, TAG_TTSC, " ");
446 return TTS_ERROR_INVALID_PARAMETER;
449 tts_client_s* client = tts_client_get(tts);
451 if (NULL == client) {
452 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
453 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
454 SLOG(LOG_DEBUG, TAG_TTSC, " ");
455 return TTS_ERROR_INVALID_PARAMETER;
458 if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
459 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
460 return TTS_ERROR_INVALID_STATE;
464 ret = tts_dbus_request_play(client->uid);
466 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
467 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
468 SLOG(LOG_DEBUG, TAG_TTSC, " ");
472 client->before_state = client->current_state;
473 client->current_state = TTS_STATE_PLAYING;
475 if (NULL != client->state_changed_cb) {
476 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
478 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
481 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
482 SLOG(LOG_DEBUG, TAG_TTSC, " ");
484 return TTS_ERROR_NONE;
488 int tts_stop(tts_h tts)
490 SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
493 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
494 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
495 SLOG(LOG_DEBUG, TAG_TTSC, " ");
496 return TTS_ERROR_INVALID_PARAMETER;
499 tts_client_s* client = tts_client_get(tts);
501 if (NULL == client) {
502 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
503 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
504 SLOG(LOG_DEBUG, TAG_TTSC, " ");
505 return TTS_ERROR_INVALID_PARAMETER;
508 if (TTS_STATE_CREATED == client->current_state) {
509 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
510 return TTS_ERROR_INVALID_STATE;
514 ret = tts_dbus_request_stop(client->uid);
516 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
517 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
518 SLOG(LOG_DEBUG, TAG_TTSC, " ");
522 client->before_state = client->current_state;
523 client->current_state = TTS_STATE_READY;
525 if (NULL != client->state_changed_cb) {
526 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
528 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
531 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
532 SLOG(LOG_DEBUG, TAG_TTSC, " ");
534 return TTS_ERROR_NONE;
538 int tts_pause(tts_h tts)
540 SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
543 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
544 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
545 SLOG(LOG_DEBUG, TAG_TTSC, " ");
546 return TTS_ERROR_INVALID_PARAMETER;
549 tts_client_s* client = tts_client_get(tts);
551 if (NULL == client) {
552 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
553 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
554 SLOG(LOG_DEBUG, TAG_TTSC, " ");
555 return TTS_ERROR_INVALID_PARAMETER;
558 if (TTS_STATE_PLAYING != client->current_state) {
559 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
560 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
561 SLOG(LOG_DEBUG, TAG_TTSC, " ");
562 return TTS_ERROR_INVALID_STATE;
566 ret = tts_dbus_request_pause(client->uid);
568 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
569 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
570 SLOG(LOG_DEBUG, TAG_TTSC, " ");
574 client->before_state = client->current_state;
575 client->current_state = TTS_STATE_PAUSED;
577 if (NULL != client->state_changed_cb) {
578 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
580 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
583 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
584 SLOG(LOG_DEBUG, TAG_TTSC, " ");
586 return TTS_ERROR_NONE;
589 static Eina_Bool __tts_notify_error(void *data)
591 tts_h tts = (tts_h)data;
593 tts_client_s* client = tts_client_get(tts);
596 if (NULL == client) {
597 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
601 if (NULL != client->error_cb) {
602 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
603 tts_client_use_callback(client);
604 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
605 tts_client_not_use_callback(client);
607 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
613 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
615 tts_client_s* client = tts_client_get_by_uid(uid);
617 if (NULL == client) {
618 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
619 return TTS_ERROR_INVALID_PARAMETER;
622 client->utt_id = utt_id;
623 client->reason = reason;
625 /* call callback function */
626 if (NULL != client->error_cb) {
627 ecore_timer_add(0, __tts_notify_error, client->tts);
629 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
635 static Eina_Bool __tts_notify_state_changed(void *data)
637 tts_h tts = (tts_h)data;
639 tts_client_s* client = tts_client_get(tts);
642 if (NULL == client) {
643 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
647 if (NULL != client->state_changed_cb) {
648 tts_client_use_callback(client);
649 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
650 tts_client_not_use_callback(client);
651 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
653 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
659 int __tts_cb_set_state(int uid, int state)
661 tts_client_s* client = tts_client_get_by_uid(uid);
662 if( NULL == client ) {
663 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
667 tts_state_e state_from_daemon = (tts_state_e)state;
669 if (client->current_state == state_from_daemon) {
670 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
674 if (NULL != client->state_changed_cb) {
675 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
677 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
680 client->before_state = client->current_state;
681 client->current_state = state_from_daemon;
686 static Eina_Bool __tts_notify_utt_started(void *data)
688 tts_h tts = (tts_h)data;
690 tts_client_s* client = tts_client_get(tts);
693 if (NULL == client) {
694 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
698 if (NULL != client->utt_started_cb) {
699 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
700 tts_client_use_callback(client);
701 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
702 tts_client_not_use_callback(client);
704 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
710 int __tts_cb_utt_started(int uid, int utt_id)
712 tts_client_s* client = tts_client_get_by_uid(uid);
714 if (NULL == client) {
715 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
716 return TTS_ERROR_INVALID_PARAMETER;
719 SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
721 client->utt_id = utt_id;
723 /* call callback function */
724 if (NULL != client->utt_started_cb) {
725 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
727 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
733 static Eina_Bool __tts_notify_utt_completed(void *data)
735 tts_h tts = (tts_h)data;
737 tts_client_s* client = tts_client_get(tts);
740 if (NULL == client) {
741 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
745 if (NULL != client->utt_completeted_cb) {
746 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
747 tts_client_use_callback(client);
748 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
749 tts_client_not_use_callback(client);
751 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
757 int __tts_cb_utt_completed(int uid, int utt_id)
759 tts_client_s* client = tts_client_get_by_uid(uid);
761 if (NULL == client) {
762 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
763 return TTS_ERROR_INVALID_PARAMETER;
766 SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
768 client->utt_id = utt_id;
770 /* call callback function */
771 if (NULL != client->utt_completeted_cb) {
772 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
774 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
780 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
782 if (NULL == tts || NULL == callback) {
783 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
784 return TTS_ERROR_INVALID_PARAMETER;
787 tts_client_s* client = tts_client_get(tts);
789 if (NULL == client) {
790 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
791 return TTS_ERROR_INVALID_PARAMETER;
794 if (TTS_STATE_CREATED != client->current_state) {
795 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'.");
796 return TTS_ERROR_INVALID_STATE;
799 client->state_changed_cb = callback;
800 client->state_changed_user_data = user_data;
802 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
807 int tts_unset_state_changed_cb(tts_h tts)
810 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
811 return TTS_ERROR_INVALID_PARAMETER;
814 tts_client_s* client = tts_client_get(tts);
816 if (NULL == client) {
817 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
818 return TTS_ERROR_INVALID_PARAMETER;
821 if (TTS_STATE_CREATED != client->current_state) {
822 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'.");
823 return TTS_ERROR_INVALID_STATE;
826 client->state_changed_cb = NULL;
827 client->state_changed_user_data = NULL;
829 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
834 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
836 if (NULL == tts || NULL == callback) {
837 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
838 return TTS_ERROR_INVALID_PARAMETER;
841 tts_client_s* client = tts_client_get(tts);
843 if (NULL == client) {
844 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
845 return TTS_ERROR_INVALID_PARAMETER;
848 if (TTS_STATE_CREATED != client->current_state) {
849 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'.");
850 return TTS_ERROR_INVALID_STATE;
853 client->utt_started_cb = callback;
854 client->utt_started_user_data = user_data;
856 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
861 int tts_unset_utterance_started_cb(tts_h tts)
864 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
865 return TTS_ERROR_INVALID_PARAMETER;
868 tts_client_s* client = tts_client_get(tts);
870 if (NULL == client) {
871 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
872 return TTS_ERROR_INVALID_PARAMETER;
875 if (TTS_STATE_CREATED != client->current_state) {
876 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'.");
877 return TTS_ERROR_INVALID_STATE;
880 client->utt_started_cb = NULL;
881 client->utt_started_user_data = NULL;
883 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
888 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
890 if (NULL == tts || NULL == callback) {
891 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
892 return TTS_ERROR_INVALID_PARAMETER;
895 tts_client_s* client = tts_client_get(tts);
897 if (NULL == client) {
898 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
899 return TTS_ERROR_INVALID_PARAMETER;
902 if (TTS_STATE_CREATED != client->current_state) {
903 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'.");
904 return TTS_ERROR_INVALID_STATE;
907 client->utt_completeted_cb = callback;
908 client->utt_completed_user_data = user_data;
910 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
915 int tts_unset_utterance_completed_cb(tts_h tts)
918 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
919 return TTS_ERROR_INVALID_PARAMETER;
922 tts_client_s* client = tts_client_get(tts);
924 if (NULL == client) {
925 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
926 return TTS_ERROR_INVALID_PARAMETER;
929 if (TTS_STATE_CREATED != client->current_state) {
930 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'.");
931 return TTS_ERROR_INVALID_STATE;
934 client->utt_completeted_cb = NULL;
935 client->utt_completed_user_data = NULL;
937 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
941 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
943 if (NULL == tts || NULL == callback) {
944 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error 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 error 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 error cb : Current state is not 'Created'.");
957 return TTS_ERROR_INVALID_STATE;
960 client->error_cb = callback;
961 client->error_user_data = user_data;
963 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
968 int tts_unset_error_cb(tts_h tts)
971 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error 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 error 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 error cb : Current state is not 'Created'.");
984 return TTS_ERROR_INVALID_STATE;
987 client->error_cb = NULL;
988 client->error_user_data = NULL;
990 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
995 int __get_cmd_line(char *file, char *buf)
1000 fp = fopen(file, "r");
1002 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
1006 memset(buf, 0, 256);
1007 fgets(buf, 256, fp);
1013 static bool _tts_is_alive()
1016 struct dirent *entry;
1017 struct stat filestat;
1023 dir = opendir("/proc");
1025 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
1029 while ((entry = readdir(dir)) != NULL) {
1030 if (0 != lstat(entry->d_name, &filestat))
1033 if (!S_ISDIR(filestat.st_mode))
1036 pid = atoi(entry->d_name);
1037 if (pid <= 0) continue;
1039 sprintf(tempPath, "/proc/%d/cmdline", pid);
1040 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1044 if ( 0 == strncmp(cmdLine, "[tts-daemon]", strlen("[tts-daemon]")) ||
1045 0 == strncmp(cmdLine, "tts-daemon", strlen("tts-daemon")) ||
1046 0 == strncmp(cmdLine, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))) {
1047 SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !!");
1053 SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon !!");
1060 static void __my_sig_child(int signo, siginfo_t *info, void *data)
1063 pid_t child_pid, child_pgid;
1065 child_pgid = getpgid(info->si_pid);
1066 SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d", info->si_pid, child_pgid);
1068 while (0 < (child_pid = waitpid(-1, &status, WNOHANG))) {
1069 if(child_pid == child_pgid)
1070 killpg(child_pgid, SIGKILL);
1076 static int __tts_check_tts_daemon()
1078 if (TRUE == _tts_is_alive())
1081 /* fork-exec tts-daemom */
1083 struct sigaction act, dummy;
1085 act.sa_handler = NULL;
1086 act.sa_sigaction = __my_sig_child;
1087 sigemptyset(&act.sa_mask);
1088 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
1090 if (sigaction(SIGCHLD, &act, &dummy) < 0) {
1091 SLOG(LOG_ERROR, TAG_TTSC, "Cannot make a signal handler");
1099 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create tts-daemon");
1104 for (i = 0;i < _NSIG;i++)
1107 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);