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