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 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_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize");
117 if (TTS_MODE_SCREEN_READER == client->mode)
118 g_is_sr_daemon_started = false;
119 else if (TTS_MODE_NOTIFICATION == client->mode)
120 g_is_noti_daemon_started = false;
122 g_is_daemon_started = false;
124 case TTS_STATE_CREATED:
125 if (NULL != g_connect_timer) {
126 SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
127 ecore_timer_del(g_connect_timer);
130 tts_client_destroy(tts);
134 if (0 == tts_client_get_size()) {
135 if (0 != tts_dbus_close_connection()) {
136 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
140 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
141 SLOG(LOG_DEBUG, TAG_TTSC, " ");
143 return TTS_ERROR_NONE;
146 int tts_set_mode(tts_h tts, tts_mode_e mode)
148 SLOG(LOG_DEBUG, TAG_TTSC, "===== Set TTS mode");
150 tts_client_s* client = tts_client_get(tts);
153 if (NULL == client) {
154 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
155 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
156 SLOG(LOG_DEBUG, TAG_TTSC, " ");
157 return TTS_ERROR_INVALID_PARAMETER;
161 if (client->current_state != TTS_STATE_CREATED) {
162 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
163 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
164 SLOG(LOG_DEBUG, TAG_TTSC, " ");
165 return TTS_ERROR_INVALID_STATE;
168 if (TTS_MODE_DEFAULT <= mode && mode <= TTS_MODE_SCREEN_READER) {
171 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid : %d", mode);
172 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
173 SLOG(LOG_DEBUG, TAG_TTSC, " ");
174 return TTS_ERROR_INVALID_PARAMETER;
177 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
178 SLOG(LOG_DEBUG, TAG_TTSC, " ");
180 return TTS_ERROR_NONE;
183 int tts_get_mode(tts_h tts, tts_mode_e* mode)
185 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get TTS mode");
187 tts_client_s* client = tts_client_get(tts);
190 if (NULL == client) {
191 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
192 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
193 SLOG(LOG_DEBUG, TAG_TTSC, " ");
194 return TTS_ERROR_INVALID_PARAMETER;
198 if (client->current_state != TTS_STATE_CREATED) {
199 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
200 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
201 SLOG(LOG_DEBUG, TAG_TTSC, " ");
202 return TTS_ERROR_INVALID_STATE;
206 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter(mode) is NULL");
207 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
208 SLOG(LOG_DEBUG, TAG_TTSC, " ");
209 return TTS_ERROR_INVALID_PARAMETER;
212 *mode = client->mode;
214 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
215 SLOG(LOG_DEBUG, TAG_TTSC, " ");
217 return TTS_ERROR_NONE;
220 static Eina_Bool __tts_connect_daemon(void *data)
222 tts_h tts = (tts_h)data;
224 tts_client_s* client = tts_client_get(tts);
227 if (NULL == client) {
228 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
233 if (0 != tts_dbus_request_hello(client->uid)) {
234 if (TTS_MODE_SCREEN_READER == client->mode) {
235 if (false == g_is_sr_daemon_started) {
236 g_is_sr_daemon_started = true;
237 __tts_check_tts_daemon(client->mode);
239 } else if (TTS_MODE_NOTIFICATION == client->mode) {
240 if (false == g_is_noti_daemon_started) {
241 g_is_noti_daemon_started = true;
242 __tts_check_tts_daemon(client->mode);
245 if (false == g_is_daemon_started) {
246 g_is_daemon_started = true;
247 __tts_check_tts_daemon(client->mode);
254 SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
256 /* do request initialize */
259 ret = tts_dbus_request_initialize(client->uid);
261 if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
262 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
264 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
267 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
270 } else if (TTS_ERROR_NONE != ret) {
271 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
273 client->reason = TTS_ERROR_TIMED_OUT;
276 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
279 /* success to connect tts-daemon */
282 client->before_state = client->current_state;
283 client->current_state = TTS_STATE_READY;
285 ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
287 g_connect_timer = NULL;
289 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
291 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
292 SLOG(LOG_DEBUG, TAG_TTSC, " ");
297 int tts_prepare(tts_h tts)
299 SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
301 tts_client_s* client = tts_client_get(tts);
304 if (NULL == client) {
305 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
306 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
307 SLOG(LOG_DEBUG, TAG_TTSC, " ");
308 return TTS_ERROR_INVALID_PARAMETER;
312 if (client->current_state != TTS_STATE_CREATED) {
313 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
314 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
315 SLOG(LOG_DEBUG, TAG_TTSC, " ");
316 return TTS_ERROR_INVALID_STATE;
319 g_connect_timer = ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
321 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
322 SLOG(LOG_DEBUG, TAG_TTSC, " ");
324 return TTS_ERROR_NONE;
327 int tts_unprepare(tts_h tts)
329 SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
331 tts_client_s* client = tts_client_get(tts);
334 if (NULL == client) {
335 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
336 return TTS_ERROR_INVALID_PARAMETER;
340 if (client->current_state != TTS_STATE_READY) {
341 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'");
342 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
343 SLOG(LOG_DEBUG, TAG_TTSC, " ");
344 return TTS_ERROR_INVALID_STATE;
347 int ret = tts_dbus_request_finalize(client->uid);
349 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
352 if (TTS_MODE_SCREEN_READER == client->mode)
353 g_is_sr_daemon_started = false;
354 else if (TTS_MODE_NOTIFICATION == client->mode)
355 g_is_noti_daemon_started = false;
357 g_is_daemon_started = false;
360 client->before_state = client->current_state;
361 client->current_state = TTS_STATE_CREATED;
363 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
365 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
366 SLOG(LOG_DEBUG, TAG_TTSC, " ");
368 return TTS_ERROR_NONE;
371 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
373 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
375 if (NULL == tts || NULL == callback) {
376 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
377 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
378 SLOG(LOG_DEBUG, TAG_TTSC, " ");
379 return TTS_ERROR_INVALID_PARAMETER;
382 tts_client_s* client = tts_client_get(tts);
385 if (NULL == client) {
386 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
387 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
388 SLOG(LOG_DEBUG, TAG_TTSC, " ");
389 return TTS_ERROR_INVALID_PARAMETER;
392 if (TTS_STATE_READY != client->current_state) {
393 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");
394 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
395 SLOG(LOG_DEBUG, TAG_TTSC, " ");
396 return TTS_ERROR_INVALID_STATE;
400 ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
402 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
405 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
406 SLOG(LOG_DEBUG, TAG_TTSC, " ");
411 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
413 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
416 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
417 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
418 SLOG(LOG_DEBUG, TAG_TTSC, " ");
419 return TTS_ERROR_INVALID_PARAMETER;
422 tts_client_s* client = tts_client_get(tts);
424 if (NULL == client) {
425 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
426 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
427 SLOG(LOG_DEBUG, TAG_TTSC, " ");
428 return TTS_ERROR_INVALID_PARAMETER;
431 if (TTS_STATE_READY != client->current_state) {
432 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
433 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
434 SLOG(LOG_DEBUG, TAG_TTSC, " ");
435 return TTS_ERROR_INVALID_STATE;
438 /* Request call remote method */
440 ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
443 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
446 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
447 SLOG(LOG_DEBUG, TAG_TTSC, " ");
452 int tts_get_max_text_count(tts_h tts, int* count)
454 if (NULL == tts || NULL == count) {
455 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
456 return TTS_ERROR_INVALID_PARAMETER;
459 tts_client_s* client = tts_client_get(tts);
461 if (NULL == client) {
462 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
463 return TTS_ERROR_INVALID_PARAMETER;
466 if (TTS_STATE_READY != client->current_state) {
467 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'.");
468 return TTS_ERROR_INVALID_STATE;
471 *count = MAX_TEXT_COUNT;
473 SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
474 return TTS_ERROR_NONE;
477 int tts_get_state(tts_h tts, tts_state_e* state)
479 if (NULL == tts || NULL == state) {
480 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
481 return TTS_ERROR_INVALID_PARAMETER;
484 tts_client_s* client = tts_client_get(tts);
486 if (NULL == client) {
487 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
488 return TTS_ERROR_INVALID_PARAMETER;
491 *state = client->current_state;
494 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'"); break;
495 case TTS_STATE_READY: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'"); break;
496 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'"); break;
497 case TTS_STATE_PAUSED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'"); break;
500 return TTS_ERROR_NONE;
503 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)
505 SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
507 if (NULL == tts || NULL == utt_id) {
508 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
509 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
510 SLOG(LOG_DEBUG, TAG_TTSC, " ");
511 return TTS_ERROR_INVALID_PARAMETER;
514 tts_client_s* client = tts_client_get(tts);
516 if (NULL == client) {
517 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
518 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
519 SLOG(LOG_DEBUG, TAG_TTSC, " ");
520 return TTS_ERROR_INVALID_PARAMETER;
523 if (TTS_STATE_CREATED == client->current_state) {
524 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
525 return TTS_ERROR_INVALID_STATE;
528 if (MAX_TEXT_COUNT < strlen(text)) {
529 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is too big.");
530 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
531 SLOG(LOG_DEBUG, TAG_TTSC, " ");
532 return TTS_ERROR_INVALID_PARAMETER;
535 /* change default language value */
538 if (NULL == language)
539 temp = strdup("default");
541 temp = strdup(language);
543 client->current_utt_id ++;
544 if (client->current_utt_id == 10000) {
545 client->current_utt_id = 1;
550 ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
552 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
554 *utt_id = client->current_utt_id;
560 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
561 SLOG(LOG_DEBUG, TAG_TTSC, " ");
566 int tts_play(tts_h tts)
568 SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
571 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
572 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
573 SLOG(LOG_DEBUG, TAG_TTSC, " ");
574 return TTS_ERROR_INVALID_PARAMETER;
577 tts_client_s* client = tts_client_get(tts);
579 if (NULL == client) {
580 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
581 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
582 SLOG(LOG_DEBUG, TAG_TTSC, " ");
583 return TTS_ERROR_INVALID_PARAMETER;
586 if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
587 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
588 return TTS_ERROR_INVALID_STATE;
592 ret = tts_dbus_request_play(client->uid);
594 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
595 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
596 SLOG(LOG_DEBUG, TAG_TTSC, " ");
600 client->before_state = client->current_state;
601 client->current_state = TTS_STATE_PLAYING;
603 if (NULL != client->state_changed_cb) {
604 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
606 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
609 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
610 SLOG(LOG_DEBUG, TAG_TTSC, " ");
612 return TTS_ERROR_NONE;
616 int tts_stop(tts_h tts)
618 SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
621 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
622 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
623 SLOG(LOG_DEBUG, TAG_TTSC, " ");
624 return TTS_ERROR_INVALID_PARAMETER;
627 tts_client_s* client = tts_client_get(tts);
629 if (NULL == client) {
630 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
631 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
632 SLOG(LOG_DEBUG, TAG_TTSC, " ");
633 return TTS_ERROR_INVALID_PARAMETER;
636 if (TTS_STATE_CREATED == client->current_state) {
637 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
638 return TTS_ERROR_INVALID_STATE;
642 ret = tts_dbus_request_stop(client->uid);
644 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
645 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
646 SLOG(LOG_DEBUG, TAG_TTSC, " ");
650 client->before_state = client->current_state;
651 client->current_state = TTS_STATE_READY;
653 if (NULL != client->state_changed_cb) {
654 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
656 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
659 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
660 SLOG(LOG_DEBUG, TAG_TTSC, " ");
662 return TTS_ERROR_NONE;
666 int tts_pause(tts_h tts)
668 SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
671 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
672 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
673 SLOG(LOG_DEBUG, TAG_TTSC, " ");
674 return TTS_ERROR_INVALID_PARAMETER;
677 tts_client_s* client = tts_client_get(tts);
679 if (NULL == client) {
680 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
681 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
682 SLOG(LOG_DEBUG, TAG_TTSC, " ");
683 return TTS_ERROR_INVALID_PARAMETER;
686 if (TTS_STATE_PLAYING != client->current_state) {
687 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
688 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
689 SLOG(LOG_DEBUG, TAG_TTSC, " ");
690 return TTS_ERROR_INVALID_STATE;
694 ret = tts_dbus_request_pause(client->uid);
696 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
697 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
698 SLOG(LOG_DEBUG, TAG_TTSC, " ");
702 client->before_state = client->current_state;
703 client->current_state = TTS_STATE_PAUSED;
705 if (NULL != client->state_changed_cb) {
706 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
708 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
711 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
712 SLOG(LOG_DEBUG, TAG_TTSC, " ");
714 return TTS_ERROR_NONE;
717 static Eina_Bool __tts_notify_error(void *data)
719 tts_h tts = (tts_h)data;
721 tts_client_s* client = tts_client_get(tts);
724 if (NULL == client) {
725 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
729 if (NULL != client->error_cb) {
730 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
731 tts_client_use_callback(client);
732 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
733 tts_client_not_use_callback(client);
735 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
741 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
743 tts_client_s* client = tts_client_get_by_uid(uid);
745 if (NULL == client) {
746 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
747 return TTS_ERROR_INVALID_PARAMETER;
750 client->utt_id = utt_id;
751 client->reason = reason;
753 /* call callback function */
754 if (NULL != client->error_cb) {
755 ecore_timer_add(0, __tts_notify_error, client->tts);
757 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
763 static Eina_Bool __tts_notify_state_changed(void *data)
765 tts_h tts = (tts_h)data;
767 tts_client_s* client = tts_client_get(tts);
770 if (NULL == client) {
771 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
775 if (NULL != client->state_changed_cb) {
776 tts_client_use_callback(client);
777 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
778 tts_client_not_use_callback(client);
779 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
781 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
787 int __tts_cb_set_state(int uid, int state)
789 tts_client_s* client = tts_client_get_by_uid(uid);
790 if( NULL == client ) {
791 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
795 tts_state_e state_from_daemon = (tts_state_e)state;
797 if (client->current_state == state_from_daemon) {
798 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
802 if (NULL != client->state_changed_cb) {
803 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
805 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
808 client->before_state = client->current_state;
809 client->current_state = state_from_daemon;
814 static Eina_Bool __tts_notify_utt_started(void *data)
816 tts_h tts = (tts_h)data;
818 tts_client_s* client = tts_client_get(tts);
821 if (NULL == client) {
822 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
826 if (NULL != client->utt_started_cb) {
827 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
828 tts_client_use_callback(client);
829 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
830 tts_client_not_use_callback(client);
832 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
838 int __tts_cb_utt_started(int uid, int utt_id)
840 tts_client_s* client = tts_client_get_by_uid(uid);
842 if (NULL == client) {
843 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
844 return TTS_ERROR_INVALID_PARAMETER;
847 SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
849 client->utt_id = utt_id;
851 /* call callback function */
852 if (NULL != client->utt_started_cb) {
853 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
855 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
861 static Eina_Bool __tts_notify_utt_completed(void *data)
863 tts_h tts = (tts_h)data;
865 tts_client_s* client = tts_client_get(tts);
868 if (NULL == client) {
869 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
873 if (NULL != client->utt_completeted_cb) {
874 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
875 tts_client_use_callback(client);
876 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
877 tts_client_not_use_callback(client);
879 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
885 int __tts_cb_utt_completed(int uid, int utt_id)
887 tts_client_s* client = tts_client_get_by_uid(uid);
889 if (NULL == client) {
890 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
891 return TTS_ERROR_INVALID_PARAMETER;
894 SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
896 client->utt_id = utt_id;
898 /* call callback function */
899 if (NULL != client->utt_completeted_cb) {
900 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
902 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
908 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
910 if (NULL == tts || NULL == callback) {
911 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
912 return TTS_ERROR_INVALID_PARAMETER;
915 tts_client_s* client = tts_client_get(tts);
917 if (NULL == client) {
918 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
919 return TTS_ERROR_INVALID_PARAMETER;
922 if (TTS_STATE_CREATED != client->current_state) {
923 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'.");
924 return TTS_ERROR_INVALID_STATE;
927 client->state_changed_cb = callback;
928 client->state_changed_user_data = user_data;
930 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
935 int tts_unset_state_changed_cb(tts_h tts)
938 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
939 return TTS_ERROR_INVALID_PARAMETER;
942 tts_client_s* client = tts_client_get(tts);
944 if (NULL == client) {
945 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
946 return TTS_ERROR_INVALID_PARAMETER;
949 if (TTS_STATE_CREATED != client->current_state) {
950 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'.");
951 return TTS_ERROR_INVALID_STATE;
954 client->state_changed_cb = NULL;
955 client->state_changed_user_data = NULL;
957 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
962 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
964 if (NULL == tts || NULL == callback) {
965 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
966 return TTS_ERROR_INVALID_PARAMETER;
969 tts_client_s* client = tts_client_get(tts);
971 if (NULL == client) {
972 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
973 return TTS_ERROR_INVALID_PARAMETER;
976 if (TTS_STATE_CREATED != client->current_state) {
977 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'.");
978 return TTS_ERROR_INVALID_STATE;
981 client->utt_started_cb = callback;
982 client->utt_started_user_data = user_data;
984 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
989 int tts_unset_utterance_started_cb(tts_h tts)
992 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
993 return TTS_ERROR_INVALID_PARAMETER;
996 tts_client_s* client = tts_client_get(tts);
998 if (NULL == client) {
999 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
1000 return TTS_ERROR_INVALID_PARAMETER;
1003 if (TTS_STATE_CREATED != client->current_state) {
1004 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'.");
1005 return TTS_ERROR_INVALID_STATE;
1008 client->utt_started_cb = NULL;
1009 client->utt_started_user_data = NULL;
1011 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
1016 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
1018 if (NULL == tts || NULL == callback) {
1019 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
1020 return TTS_ERROR_INVALID_PARAMETER;
1023 tts_client_s* client = tts_client_get(tts);
1025 if (NULL == client) {
1026 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
1027 return TTS_ERROR_INVALID_PARAMETER;
1030 if (TTS_STATE_CREATED != client->current_state) {
1031 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'.");
1032 return TTS_ERROR_INVALID_STATE;
1035 client->utt_completeted_cb = callback;
1036 client->utt_completed_user_data = user_data;
1038 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
1043 int tts_unset_utterance_completed_cb(tts_h tts)
1046 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
1047 return TTS_ERROR_INVALID_PARAMETER;
1050 tts_client_s* client = tts_client_get(tts);
1052 if (NULL == client) {
1053 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
1054 return TTS_ERROR_INVALID_PARAMETER;
1057 if (TTS_STATE_CREATED != client->current_state) {
1058 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'.");
1059 return TTS_ERROR_INVALID_STATE;
1062 client->utt_completeted_cb = NULL;
1063 client->utt_completed_user_data = NULL;
1065 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
1069 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
1071 if (NULL == tts || NULL == callback) {
1072 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
1073 return TTS_ERROR_INVALID_PARAMETER;
1076 tts_client_s* client = tts_client_get(tts);
1078 if (NULL == client) {
1079 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
1080 return TTS_ERROR_INVALID_PARAMETER;
1083 if (TTS_STATE_CREATED != client->current_state) {
1084 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'.");
1085 return TTS_ERROR_INVALID_STATE;
1088 client->error_cb = callback;
1089 client->error_user_data = user_data;
1091 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
1096 int tts_unset_error_cb(tts_h tts)
1099 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
1100 return TTS_ERROR_INVALID_PARAMETER;
1103 tts_client_s* client = tts_client_get(tts);
1105 if (NULL == client) {
1106 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
1107 return TTS_ERROR_INVALID_PARAMETER;
1110 if (TTS_STATE_CREATED != client->current_state) {
1111 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'.");
1112 return TTS_ERROR_INVALID_STATE;
1115 client->error_cb = NULL;
1116 client->error_user_data = NULL;
1118 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
1123 static int __get_cmd_line(char *file, char *buf)
1127 fp = fopen(file, "r");
1129 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
1133 memset(buf, 0, 256);
1134 if (NULL == fgets(buf, 256, fp)) {
1135 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to fget command line");
1144 static bool __tts_is_alive(char* daemon_path)
1147 struct dirent *entry;
1148 struct stat filestat;
1151 char cmdLine[256] = {'\0',};
1152 char tempPath[256] = {'\0',};
1154 dir = opendir("/proc");
1156 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
1160 while ((entry = readdir(dir)) != NULL) {
1161 if (0 != lstat(entry->d_name, &filestat)) {
1165 if (!S_ISDIR(filestat.st_mode)) {
1169 pid = atoi(entry->d_name);
1170 if (pid <= 0) continue;
1172 sprintf(tempPath, "/proc/%d/cmdline", pid);
1173 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1177 if (0 == strncmp(cmdLine, daemon_path, strlen(daemon_path))) {
1178 SLOG(LOG_DEBUG, TAG_TTSC, "%s is ALIVE !!", daemon_path);
1184 SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO %s !!", daemon_path);
1190 static int __tts_check_tts_daemon(tts_mode_e mode)
1192 char daemon_path[64] = {'\0',};
1195 if (TTS_MODE_DEFAULT == mode) {
1196 strcpy(daemon_path, "/usr/bin/tts-daemon");
1197 } else if (TTS_MODE_NOTIFICATION == mode) {
1198 strcpy(daemon_path, "/usr/bin/tts-daemon-noti");
1199 } else if (TTS_MODE_SCREEN_READER == mode) {
1200 strcpy(daemon_path, "/usr/bin/tts-daemon-sr");
1202 SLOG(LOG_ERROR, TAG_TTSC, "mode is not valid");
1206 if (TRUE == __tts_is_alive(daemon_path)) {
1210 /* fork-exec daemom */
1215 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create daemon");
1220 for (i = 0;i < _NSIG;i++)
1223 execl(daemon_path, daemon_path, NULL);