Tizen 2.1 base
[platform/core/uifw/tts.git] / client / tts.c
1 /*
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.
12 */
13
14
15 #include <sys/wait.h>
16 #include <Ecore.h>
17 #include <sys/stat.h>
18 #include <sys/types.h> 
19 #include <dirent.h>
20
21 #include "tts_main.h"
22 #include "tts_client.h"
23 #include "tts_dbus.h"
24
25 #define MAX_TEXT_COUNT 1000
26
27 static bool g_is_daemon_started = false;
28
29 static Ecore_Timer* g_connect_timer = NULL;
30
31 /* Function definition */
32 static int __tts_check_tts_daemon();
33 static Eina_Bool __tts_notify_state_changed(void *data);
34 static Eina_Bool __tts_notify_error(void *data);
35
36 int tts_create(tts_h* tts)
37 {
38         SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
39         
40         /* check param */
41         if (NULL == tts) {
42                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
43                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
44                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
45                 return TTS_ERROR_INVALID_PARAMETER;
46         }       
47
48         if (0 == tts_client_get_size()) {
49                 if (0 != tts_dbus_open_connection()) {
50                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
51                         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
52                         SLOG(LOG_DEBUG, TAG_TTSC, " ");
53                         return TTS_ERROR_OPERATION_FAILED;
54                 }
55         }
56
57         if (0 != tts_client_new(tts)) {
58                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
59                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
60                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
61                 return TTS_ERROR_OUT_OF_MEMORY;
62         }
63
64         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
65         SLOG(LOG_DEBUG, TAG_TTSC, " ");
66
67         return TTS_ERROR_NONE;
68 }
69
70 int tts_destroy(tts_h tts)
71 {
72         SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
73
74         if (NULL == tts) {
75                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
76                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
77                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
78                 return TTS_ERROR_INVALID_PARAMETER;
79         }
80
81         tts_client_s* client = tts_client_get(tts);
82
83         /* check handle */
84         if (NULL == client) {
85                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
86                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
87                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
88                 return TTS_ERROR_INVALID_PARAMETER;
89         }
90
91         /* check used callback */
92         if (0 != tts_client_get_use_callback(client)) {
93                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot destroy in Callback function");
94                 return TTS_ERROR_OPERATION_FAILED;
95         }
96
97         int ret = -1;
98
99         /* check state */
100         switch (client->current_state) {
101         case TTS_STATE_PAUSED:
102         case TTS_STATE_PLAYING:
103         case TTS_STATE_READY:
104                 /* Request Finalize */
105                 ret = tts_dbus_request_finalize(client->uid);
106                 if (0 != ret) {
107                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize");
108                 }
109                 g_is_daemon_started = false;
110         case TTS_STATE_CREATED:
111                 if (NULL != g_connect_timer) {
112                         SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
113                         ecore_timer_del(g_connect_timer);
114                 }
115                 /* Free resources */
116                 tts_client_destroy(tts);
117                 break;
118         }
119  
120         if (0 == tts_client_get_size()) {
121                 if (0 != tts_dbus_close_connection()) {
122                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
123                 }
124         }
125
126         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
127         SLOG(LOG_DEBUG, TAG_TTSC, " ");
128
129         return TTS_ERROR_NONE;
130 }
131
132 static Eina_Bool __tts_connect_daemon(void *data)
133 {
134         tts_h tts = (tts_h)data;
135
136         tts_client_s* client = tts_client_get(tts);
137
138         /* check handle */
139         if (NULL == client) {
140                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
141                 return EINA_FALSE;
142         }
143
144         /* Send hello */
145         if (0 != tts_dbus_request_hello()) {
146                 if (false == g_is_daemon_started) {
147                         g_is_daemon_started = true;
148                         __tts_check_tts_daemon();
149                 }
150                 return EINA_TRUE;
151         }
152
153         SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
154         
155         /* do request initialize */
156         int ret = -1;
157
158         ret = tts_dbus_request_initialize(client->uid);
159
160         if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
161                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
162                 
163                 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
164                 client->utt_id = -1;
165
166                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
167                 return EINA_FALSE;
168
169         } else if (TTS_ERROR_NONE != ret) {
170                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
171
172                 client->reason = TTS_ERROR_TIMED_OUT;
173                 client->utt_id = -1;
174
175                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
176                 return EINA_FALSE;
177         } else {
178                 /* success to connect tts-daemon */
179         }
180
181         client->before_state = client->current_state;
182         client->current_state = TTS_STATE_READY;
183
184         ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
185
186         g_connect_timer = NULL;
187
188         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
189
190         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
191         SLOG(LOG_DEBUG, TAG_TTSC, " ");
192
193         return EINA_FALSE;
194 }
195
196 int tts_prepare(tts_h tts)
197 {
198         SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
199
200         tts_client_s* client = tts_client_get(tts);
201
202         /* check handle */
203         if (NULL == client) {
204                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
205                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
206                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
207                 return TTS_ERROR_INVALID_PARAMETER;
208         }
209
210         /* check state */
211         if (client->current_state != TTS_STATE_CREATED) {
212                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'"); 
213                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
214                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
215                 return TTS_ERROR_INVALID_STATE;
216         }
217
218         g_connect_timer = ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
219
220         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
221         SLOG(LOG_DEBUG, TAG_TTSC, " ");
222
223         return TTS_ERROR_NONE;
224 }
225
226 int tts_unprepare(tts_h tts)
227 {
228         SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
229
230         tts_client_s* client = tts_client_get(tts);
231
232         /* check handle */
233         if (NULL == client) {
234                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
235                 return TTS_ERROR_INVALID_PARAMETER;
236         }
237
238         /* check state */
239         if (client->current_state != TTS_STATE_READY) {
240                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'"); 
241                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
242                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
243                 return TTS_ERROR_INVALID_STATE;
244         }
245
246         int ret = tts_dbus_request_finalize(client->uid);
247         if (0 != ret) {
248                 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
249         }
250         g_is_daemon_started = false;
251
252         client->before_state = client->current_state;
253         client->current_state = TTS_STATE_CREATED;
254
255         ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
256
257         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
258         SLOG(LOG_DEBUG, TAG_TTSC, " ");
259
260         return TTS_ERROR_NONE;
261 }
262
263 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
264 {
265         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
266
267         if (NULL == tts || NULL == callback) {
268                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
269                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
270                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
271                 return TTS_ERROR_INVALID_PARAMETER;
272         }
273
274         tts_client_s* client = tts_client_get(tts);
275
276         /* check handle */
277         if (NULL == client) {
278                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
279                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
280                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
281                 return TTS_ERROR_INVALID_PARAMETER;
282         }
283
284         if (TTS_STATE_READY != client->current_state) {
285                 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");  
286                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
287                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
288                 return TTS_ERROR_INVALID_STATE;
289         }
290
291         int ret = 0;
292         ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
293         if (0 != ret) {
294                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
295         }    
296
297         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
298         SLOG(LOG_DEBUG, TAG_TTSC, " ");
299
300         return ret;
301 }
302
303 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
304 {
305         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
306
307         if (NULL == tts) {
308                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
309                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
310                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
311                 return TTS_ERROR_INVALID_PARAMETER;
312
313         }
314         tts_client_s* client = tts_client_get(tts);
315
316         if (NULL == client) {
317                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
318                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
319                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
320                 return TTS_ERROR_INVALID_PARAMETER;
321         }
322
323         if (TTS_STATE_READY != client->current_state) {
324                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
325                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
326                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
327                 return TTS_ERROR_INVALID_STATE;
328         }
329
330         /* Request call remote method */
331         int ret = 0;
332         ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
333     
334         if (0 != ret) {
335                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
336         }
337         
338         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
339         SLOG(LOG_DEBUG, TAG_TTSC, " ");
340
341         return ret;
342 }
343
344 int tts_get_max_text_count(tts_h tts, int* count)
345 {
346         if (NULL == tts || NULL == count) {
347                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
348                 return TTS_ERROR_INVALID_PARAMETER;
349         }
350
351         tts_client_s* client = tts_client_get(tts);
352
353         if (NULL == client) {
354                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
355                 return TTS_ERROR_INVALID_PARAMETER;
356         }
357         
358         if (TTS_STATE_READY != client->current_state) {
359                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'."); 
360                 return TTS_ERROR_INVALID_STATE;
361         }
362
363         *count = MAX_TEXT_COUNT;
364
365         SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
366         return TTS_ERROR_NONE;
367 }
368
369 int tts_get_state(tts_h tts, tts_state_e* state)
370 {
371         if (NULL == tts || NULL == state) {
372                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
373                 return TTS_ERROR_INVALID_PARAMETER;
374         }
375
376         tts_client_s* client = tts_client_get(tts);
377
378         if (NULL == client) {
379                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
380                 return TTS_ERROR_INVALID_PARAMETER;
381         }
382
383         *state = client->current_state;
384
385         switch(*state) {
386                 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'");        break;
387                 case TTS_STATE_READY:   SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'");          break;
388                 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'");        break;
389                 case TTS_STATE_PAUSED:  SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'");         break;
390         }
391
392         return TTS_ERROR_NONE;
393 }
394
395 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)
396 {
397         SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
398
399         if (NULL == tts || NULL == utt_id) {
400                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
401                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
402                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
403                 return TTS_ERROR_INVALID_PARAMETER;
404         }
405
406         tts_client_s* client = tts_client_get(tts);
407
408         if (NULL == client) {
409                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
410                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
411                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
412                 return TTS_ERROR_INVALID_PARAMETER;
413         }
414
415         if (TTS_STATE_CREATED == client->current_state) {
416                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'."); 
417                 return TTS_ERROR_INVALID_STATE;
418         }
419
420         /* change default language value */
421         char* temp = NULL;
422
423         if (NULL == language)
424                 temp = strdup("default");
425         else 
426                 temp = strdup(language);
427
428         client->current_utt_id ++;
429         if (client->current_utt_id == 10000) {
430                 client->current_utt_id = 1;
431         }
432
433         /* do request */
434         int ret = 0;
435         ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
436         if (0 != ret) {
437                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
438         }
439
440         *utt_id = client->current_utt_id;
441
442         if (NULL != temp)
443                 free(temp);
444
445         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
446         SLOG(LOG_DEBUG, TAG_TTSC, " ");
447
448         return ret;
449 }
450
451 int tts_play(tts_h tts)
452 {
453         SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
454
455         if (NULL == tts) {
456                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
457                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
458                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
459                 return TTS_ERROR_INVALID_PARAMETER;
460         }
461
462         tts_client_s* client = tts_client_get(tts);
463
464         if (NULL == client) {
465                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
466                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
467                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
468                 return TTS_ERROR_INVALID_PARAMETER;
469         }
470
471         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
472                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid."); 
473                 return TTS_ERROR_INVALID_STATE;
474         } 
475
476         int ret = 0;
477         ret = tts_dbus_request_play(client->uid);
478         if (0 != ret) {
479                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
480                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
481                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
482                 return ret;
483         }
484
485         client->before_state = client->current_state;
486         client->current_state = TTS_STATE_PLAYING;
487
488         if (NULL != client->state_changed_cb) {
489                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
490         } else {
491                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
492         }
493
494         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
495         SLOG(LOG_DEBUG, TAG_TTSC, " ");
496
497         return TTS_ERROR_NONE;
498 }
499
500
501 int tts_stop(tts_h tts)
502 {
503         SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
504
505         if (NULL == tts) {
506                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
507                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
508                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
509                 return TTS_ERROR_INVALID_PARAMETER;
510         }
511
512         tts_client_s* client = tts_client_get(tts);
513
514         if (NULL == client) {
515                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
516                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
517                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
518                 return TTS_ERROR_INVALID_PARAMETER;
519         }
520
521         if (TTS_STATE_CREATED == client->current_state) {
522                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'."); 
523                 return TTS_ERROR_INVALID_STATE;
524         }
525
526         int ret = 0;
527         ret = tts_dbus_request_stop(client->uid);
528         if (0 != ret) {
529                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
530                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
531                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
532                 return ret;
533         }       
534
535         client->before_state = client->current_state;
536         client->current_state = TTS_STATE_READY;
537
538         if (NULL != client->state_changed_cb) {
539                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
540         } else {
541                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
542         }
543
544         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
545         SLOG(LOG_DEBUG, TAG_TTSC, " ");
546
547         return TTS_ERROR_NONE;
548 }
549
550
551 int tts_pause(tts_h tts)
552 {
553         SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
554
555         if (NULL == tts) {
556                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
557                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
558                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
559                 return TTS_ERROR_INVALID_PARAMETER;
560         }
561
562         tts_client_s* client = tts_client_get(tts);
563
564         if (NULL == client) {
565                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
566                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
567                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
568                 return TTS_ERROR_INVALID_PARAMETER;
569         }
570
571         if (TTS_STATE_PLAYING != client->current_state) {
572                 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");    
573                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
574                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
575                 return TTS_ERROR_INVALID_STATE;
576         }       
577         
578         int ret = 0;
579         ret = tts_dbus_request_pause(client->uid);
580         if (0 != ret) {
581                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
582                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
583                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
584                 return ret;
585         }
586
587         client->before_state = client->current_state;
588         client->current_state = TTS_STATE_PAUSED;
589
590         if (NULL != client->state_changed_cb) {
591                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
592         } else {
593                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
594         }
595
596         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
597         SLOG(LOG_DEBUG, TAG_TTSC, " ");
598
599         return TTS_ERROR_NONE;
600 }
601
602 static Eina_Bool __tts_notify_error(void *data)
603 {
604         tts_h tts = (tts_h)data;
605
606         tts_client_s* client = tts_client_get(tts);
607
608         /* check handle */
609         if (NULL == client) {
610                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
611                 return EINA_FALSE;
612         }
613
614         if (NULL != client->error_cb) {
615                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
616                 tts_client_use_callback(client);
617                 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
618                 tts_client_not_use_callback(client);
619         } else {
620                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
621         }
622
623         return EINA_FALSE;
624 }
625
626 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
627 {
628         tts_client_s* client = tts_client_get_by_uid(uid);
629
630         if (NULL == client) {
631                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
632                 return TTS_ERROR_INVALID_PARAMETER;
633         }
634
635         client->utt_id = utt_id;
636         client->reason = reason;
637
638         /* call callback function */
639         if (NULL != client->error_cb) {
640                 ecore_timer_add(0, __tts_notify_error, client->tts);
641         } else {
642                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
643         }
644         
645         return 0;
646 }
647
648 static Eina_Bool __tts_notify_state_changed(void *data)
649 {
650         tts_h tts = (tts_h)data;
651
652         tts_client_s* client = tts_client_get(tts);
653
654         /* check handle */
655         if (NULL == client) {
656                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
657                 return EINA_FALSE;
658         }
659
660         if (NULL != client->state_changed_cb) {
661                 tts_client_use_callback(client);
662                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data); 
663                 tts_client_not_use_callback(client);
664                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
665         } else {
666                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
667         }
668
669         return EINA_FALSE;
670 }
671
672 int __tts_cb_set_state(int uid, int state)
673 {
674         tts_client_s* client = tts_client_get_by_uid(uid);
675         if( NULL == client ) {
676                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
677                 return -1;
678         }
679
680         tts_state_e state_from_daemon = (tts_state_e)state;
681
682         if (client->current_state == state_from_daemon) {
683                 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
684                 return 0;
685         }
686
687         if (NULL != client->state_changed_cb) {
688                 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
689         } else {
690                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
691         }
692
693         client->before_state = client->current_state;
694         client->current_state = state_from_daemon;
695
696         return 0;
697 }
698
699 static Eina_Bool __tts_notify_utt_started(void *data)
700 {
701         tts_h tts = (tts_h)data;
702
703         tts_client_s* client = tts_client_get(tts);
704
705         /* check handle */
706         if (NULL == client) {
707                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
708                 return EINA_FALSE;
709         }
710         
711         if (NULL != client->utt_started_cb) {
712                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
713                 tts_client_use_callback(client);
714                 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
715                 tts_client_not_use_callback(client);
716         } else {
717                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
718         }
719
720         return EINA_FALSE;
721 }
722
723 int __tts_cb_utt_started(int uid, int utt_id)
724 {
725         tts_client_s* client = tts_client_get_by_uid(uid);
726
727         if (NULL == client) {
728                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
729                 return TTS_ERROR_INVALID_PARAMETER;
730         }
731
732         SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
733
734         client->utt_id = utt_id;
735
736         /* call callback function */
737         if (NULL != client->utt_started_cb) {
738                 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
739         } else {
740                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
741         }
742
743         return 0;
744 }
745
746 static Eina_Bool __tts_notify_utt_completed(void *data)
747 {
748         tts_h tts = (tts_h)data;
749
750         tts_client_s* client = tts_client_get(tts);
751
752         /* check handle */
753         if (NULL == client) {
754                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
755                 return EINA_FALSE;
756         }
757
758         if (NULL != client->utt_completeted_cb) {
759                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
760                 tts_client_use_callback(client);
761                 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
762                 tts_client_not_use_callback(client);
763         } else {
764                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
765         }
766
767         return EINA_FALSE;
768 }
769
770 int __tts_cb_utt_completed(int uid, int utt_id)
771 {
772         tts_client_s* client = tts_client_get_by_uid(uid);
773
774         if (NULL == client) {
775                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
776                 return TTS_ERROR_INVALID_PARAMETER;
777         }
778
779         SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
780
781         client->utt_id = utt_id;
782
783         /* call callback function */
784         if (NULL != client->utt_completeted_cb) {
785                 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
786         } else {
787                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
788         }
789
790         return 0;
791 }
792
793 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
794 {
795         if (NULL == tts || NULL == callback) {
796                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
797                 return TTS_ERROR_INVALID_PARAMETER;
798         }
799
800         tts_client_s* client = tts_client_get(tts);
801
802         if (NULL == client) {
803                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
804                 return TTS_ERROR_INVALID_PARAMETER;
805         }
806
807         if (TTS_STATE_CREATED != client->current_state) {
808                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'."); 
809                 return TTS_ERROR_INVALID_STATE;
810         }
811
812         client->state_changed_cb = callback;
813         client->state_changed_user_data = user_data;
814
815         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
816
817         return 0;
818 }
819
820 int tts_unset_state_changed_cb(tts_h tts)
821 {
822         if (NULL == tts) {
823                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
824                 return TTS_ERROR_INVALID_PARAMETER;
825         }
826
827         tts_client_s* client = tts_client_get(tts);
828
829         if (NULL == client) {
830                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
831                 return TTS_ERROR_INVALID_PARAMETER;
832         }
833
834         if (TTS_STATE_CREATED != client->current_state) {
835                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'."); 
836                 return TTS_ERROR_INVALID_STATE;
837         }
838
839         client->state_changed_cb = NULL;
840         client->state_changed_user_data = NULL;
841
842         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
843
844         return 0;
845 }
846
847 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
848 {
849         if (NULL == tts || NULL == callback) {
850                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
851                 return TTS_ERROR_INVALID_PARAMETER;
852         }
853
854         tts_client_s* client = tts_client_get(tts);
855
856         if (NULL == client) {
857                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
858                 return TTS_ERROR_INVALID_PARAMETER;
859         }
860
861         if (TTS_STATE_CREATED != client->current_state) {
862                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'."); 
863                 return TTS_ERROR_INVALID_STATE;
864         }
865
866         client->utt_started_cb = callback;
867         client->utt_started_user_data = user_data;
868
869         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
870         
871         return 0;
872 }
873
874 int tts_unset_utterance_started_cb(tts_h tts)
875 {
876         if (NULL == tts) {
877                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
878                 return TTS_ERROR_INVALID_PARAMETER;
879         }
880
881         tts_client_s* client = tts_client_get(tts);
882
883         if (NULL == client) {
884                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
885                 return TTS_ERROR_INVALID_PARAMETER;
886         }
887
888         if (TTS_STATE_CREATED != client->current_state) {
889                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'."); 
890                 return TTS_ERROR_INVALID_STATE;
891         }
892
893         client->utt_started_cb = NULL;
894         client->utt_started_user_data = NULL;
895
896         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
897         
898         return 0;
899 }
900
901 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
902 {
903         if (NULL == tts || NULL == callback) {
904                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
905                 return TTS_ERROR_INVALID_PARAMETER;
906         }
907
908         tts_client_s* client = tts_client_get(tts);
909
910         if (NULL == client) {
911                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
912                 return TTS_ERROR_INVALID_PARAMETER;
913         }
914
915         if (TTS_STATE_CREATED != client->current_state) {
916                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'."); 
917                 return TTS_ERROR_INVALID_STATE;
918         }
919
920         client->utt_completeted_cb = callback;
921         client->utt_completed_user_data = user_data;
922
923         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
924         
925         return 0;
926 }
927
928 int tts_unset_utterance_completed_cb(tts_h tts)
929 {
930         if (NULL == tts) {
931                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
932                 return TTS_ERROR_INVALID_PARAMETER;
933         }
934
935         tts_client_s* client = tts_client_get(tts);
936
937         if (NULL == client) {
938                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
939                 return TTS_ERROR_INVALID_PARAMETER;
940         }
941
942         if (TTS_STATE_CREATED != client->current_state) {
943                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'."); 
944                 return TTS_ERROR_INVALID_STATE;
945         }
946
947         client->utt_completeted_cb = NULL;
948         client->utt_completed_user_data = NULL;
949
950         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
951         return 0;
952 }
953
954 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
955 {
956         if (NULL == tts || NULL == callback) {
957                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
958                 return TTS_ERROR_INVALID_PARAMETER;
959         }
960
961         tts_client_s* client = tts_client_get(tts);
962
963         if (NULL == client) {
964                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
965                 return TTS_ERROR_INVALID_PARAMETER;
966         }
967
968         if (TTS_STATE_CREATED != client->current_state) {
969                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'."); 
970                 return TTS_ERROR_INVALID_STATE;
971         }
972
973         client->error_cb = callback;
974         client->error_user_data = user_data;
975
976         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
977         
978         return 0;
979 }
980
981 int tts_unset_error_cb(tts_h tts)
982 {
983         if (NULL == tts) {
984                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
985                 return TTS_ERROR_INVALID_PARAMETER;
986         }
987
988         tts_client_s* client = tts_client_get(tts);
989
990         if (NULL == client) {
991                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
992                 return TTS_ERROR_INVALID_PARAMETER;
993         }
994         
995         if (TTS_STATE_CREATED != client->current_state) {
996                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'."); 
997                 return TTS_ERROR_INVALID_STATE;
998         }
999
1000         client->error_cb = NULL;
1001         client->error_user_data = NULL;
1002
1003         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
1004
1005         return 0;
1006 }
1007
1008 int __get_cmd_line(char *file, char *buf) 
1009 {
1010         FILE *fp = NULL;
1011
1012         fp = fopen(file, "r");
1013         if (fp == NULL) {
1014                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
1015                 return -1;
1016         }
1017
1018         memset(buf, 0, 256);
1019         if (NULL == fgets(buf, 256, fp)) {
1020                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to fget command line");
1021                 fclose(fp);
1022                 return -1;
1023         }
1024         fclose(fp);
1025         return 0;
1026 }
1027
1028 static bool _tts_is_alive()
1029 {
1030         DIR *dir;
1031         struct dirent *entry;
1032         struct stat filestat;
1033         
1034         int pid;
1035         char cmdLine[256];
1036         char tempPath[256];
1037
1038         dir  = opendir("/proc");
1039         if (NULL == dir) {
1040                 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
1041                 return FALSE;
1042         }
1043
1044         while ((entry = readdir(dir)) != NULL) {
1045                 if (0 != lstat(entry->d_name, &filestat))
1046                         continue;
1047
1048                 if (!S_ISDIR(filestat.st_mode))
1049                         continue;
1050
1051                 pid = atoi(entry->d_name);
1052                 if (pid <= 0) continue;
1053
1054                 sprintf(tempPath, "/proc/%d/cmdline", pid);
1055                 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1056                         continue;
1057                 }
1058
1059                 if ( 0 == strncmp(cmdLine, "[tts-daemon]", strlen("[tts-daemon]")) ||
1060                         0 == strncmp(cmdLine, "tts-daemon", strlen("tts-daemon")) ||
1061                         0 == strncmp(cmdLine, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))) {
1062                                 SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !!");
1063                                 closedir(dir);
1064                                 return TRUE;
1065                 }
1066         }
1067
1068         SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon !!");
1069
1070         closedir(dir);
1071         return FALSE;
1072 }
1073
1074 static int __tts_check_tts_daemon()
1075 {
1076         if (TRUE == _tts_is_alive()) {
1077                 return 0;
1078         }
1079         
1080         /* fork-exec tts-daemom */
1081         int pid, i;
1082
1083         pid = fork();
1084
1085         switch(pid) {
1086         case -1:
1087                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create tts-daemon");
1088                 break;
1089
1090         case 0:
1091                 setsid();
1092                 for (i = 0;i < _NSIG;i++)
1093                         signal(i, SIG_DFL);
1094
1095                 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);
1096                 break;
1097
1098         default:
1099                 break;
1100         }
1101
1102         return 0;
1103 }