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