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