beb0d18c8d2ecd8a7113a7289543da466f9b1435
[platform/core/uifw/stt.git] / client / stt.c
1 /*
2 *  Copyright (c) 2011-2016 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 #include <aul.h>
15 #include <cynara-client.h>
16 #include <cynara-error.h>
17 #include <cynara-session.h>
18 #include <dirent.h>
19 #include <Ecore.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <system_info.h>
26 #include <unistd.h>
27 #include <buxton2.h>
28
29 #include "stt.h"
30 #include "stt_client.h"
31 #include "stt_dbus.h"
32 #include "stt_config_mgr.h"
33 #include "stt_internal.h"
34 #include "stt_main.h"
35
36
37 static void __stt_notify_state_changed(void *data);
38 static void __stt_notify_error(void *data);
39
40 static Ecore_Timer* g_connect_timer = NULL;
41 static float g_volume_db = 0;
42
43 static int g_feature_enabled = -1;
44
45 static int g_privilege_allowed = -1;
46 static int g_privilege_applaunch_allowed = -1;
47
48 static cynara *p_cynara = NULL;
49
50 static bool g_err_callback_status = false;
51
52 const char* stt_tag()
53 {
54         //LCOV_EXCL_START
55         return "sttc";
56         //LCOV_EXCL_STOP
57 }
58
59 static int __stt_get_feature_enabled()
60 {
61         if (0 == g_feature_enabled) {
62                 //LCOV_EXCL_START
63                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
64                 return STT_ERROR_NOT_SUPPORTED;
65                 //LCOV_EXCL_STOP
66         } else if (-1 == g_feature_enabled) {
67                 bool stt_supported = false;
68                 bool mic_supported = false;
69                 if (0 == system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
70                         if (0 == system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
71                                 if (false == stt_supported || false == mic_supported) {
72                                         //LCOV_EXCL_START
73                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
74                                         g_feature_enabled = 0;
75                                         return STT_ERROR_NOT_SUPPORTED;
76                                         //LCOV_EXCL_STOP
77                                 }
78
79                                 g_feature_enabled = 1;
80                         } else {
81                                 //LCOV_EXCL_START
82                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
83                                 return STT_ERROR_NOT_SUPPORTED;
84                                 //LCOV_EXCL_STOP
85                         }
86                 } else {
87                         //LCOV_EXCL_START
88                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
89                         return STT_ERROR_NOT_SUPPORTED;
90                         //LCOV_EXCL_STOP
91                 }
92         }
93
94         return 0;
95 }
96
97 static int __check_privilege_initialize()
98 {
99         int ret = cynara_initialize(&p_cynara, NULL);
100         if (CYNARA_API_SUCCESS != ret)
101                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to initialize"); //LCOV_EXCL_LINE
102
103         return ret == CYNARA_API_SUCCESS;
104 }
105
106 static bool __check_privilege(const char* uid, const char * privilege)
107 {
108         FILE *fp = NULL;
109         char label_path[1024] = "/proc/self/attr/current";
110         char smack_label[1024] = {'\0',};
111
112         if (!p_cynara) {
113                 return false;
114         }
115
116         fp = fopen(label_path, "r");
117         if (fp != NULL) {
118                 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
119                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to fread"); //LCOV_EXCL_LINE
120
121                 fclose(fp);
122         }
123
124         pid_t pid = getpid();
125         char *session = cynara_session_from_pid(pid);
126         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
127         SLOG(LOG_DEBUG, TAG_STTC, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
128         if (session) {
129                 free(session);
130                 session = NULL;
131         }
132
133         if (ret != CYNARA_API_ACCESS_ALLOWED)
134                 return false;
135         return true;
136 }
137
138 static void __check_privilege_deinitialize()
139 {
140         if (p_cynara)
141                 cynara_finish(p_cynara);
142         p_cynara = NULL;
143 }
144
145 static int __stt_check_privilege()
146 {
147         char uid[16];
148
149         if (0 == g_privilege_allowed) {
150                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied"); //LCOV_EXCL_LINE
151                 return STT_ERROR_PERMISSION_DENIED;
152         } else if (-1 == g_privilege_allowed) {
153                 if (false == __check_privilege_initialize()) {
154                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed"); //LCOV_EXCL_LINE
155                         return STT_ERROR_PERMISSION_DENIED;
156                 }
157                 snprintf(uid, 16, "%d", getuid());
158                 if (false == __check_privilege(uid, STT_PRIVILEGE_RECORDER)) {
159                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied"); //LCOV_EXCL_LINE
160                         g_privilege_allowed = 0;
161                         __check_privilege_deinitialize();
162                         return STT_ERROR_PERMISSION_DENIED;
163                 }
164                 __check_privilege_deinitialize();
165         }
166
167         g_privilege_allowed = 1;
168         return STT_ERROR_NONE;
169 }
170
171 static int __stt_check_privilege_for_applaunch()
172 {
173         char uid[16];
174
175         if (0 == g_privilege_applaunch_allowed) {
176                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission for applaunch is denied"); //LCOV_EXCL_LINE
177                 return STT_ERROR_PERMISSION_DENIED;
178         } else if (-1 == g_privilege_applaunch_allowed) {
179                 if (false == __check_privilege_initialize()) {
180                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed (applaunch)"); //LCOV_EXCL_LINE
181                         return STT_ERROR_PERMISSION_DENIED;
182                 }
183                 snprintf(uid, 16, "%d", getuid());
184                 if (false == __check_privilege(uid, STT_PRIVILEGE_APPLAUNCH)) {
185                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied : appmanager.launch"); //LCOV_EXCL_LINE
186                         g_privilege_applaunch_allowed = 0;
187                         __check_privilege_deinitialize();
188                         return STT_ERROR_PERMISSION_DENIED;
189                 }
190                 __check_privilege_deinitialize();
191         }
192
193         g_privilege_applaunch_allowed = 1;
194         return STT_ERROR_NONE;
195 }
196
197 static const char* __stt_get_error_code(stt_error_e err)
198 {
199         //LCOV_EXCL_START
200         switch (err) {
201         case STT_ERROR_NONE:                    return "STT_ERROR_NONE";
202         case STT_ERROR_OUT_OF_MEMORY:           return "STT_ERROR_OUT_OF_MEMORY";
203         case STT_ERROR_IO_ERROR:                return "STT_ERROR_IO_ERROR";
204         case STT_ERROR_INVALID_PARAMETER:       return "STT_ERROR_INVALID_PARAMETER";
205         case STT_ERROR_TIMED_OUT:               return "STT_ERROR_TIMED_OUT";
206         case STT_ERROR_RECORDER_BUSY:           return "STT_ERROR_RECORDER_BUSY";
207         case STT_ERROR_OUT_OF_NETWORK:          return "STT_ERROR_OUT_OF_NETWORK";
208         case STT_ERROR_PERMISSION_DENIED:       return "STT_ERROR_PERMISSION_DENIED";
209         case STT_ERROR_NOT_SUPPORTED:           return "STT_ERROR_NOT_SUPPORTED";
210         case STT_ERROR_INVALID_STATE:           return "STT_ERROR_INVALID_STATE";
211         case STT_ERROR_INVALID_LANGUAGE:        return "STT_ERROR_INVALID_LANGUAGE";
212         case STT_ERROR_ENGINE_NOT_FOUND:        return "STT_ERROR_ENGINE_NOT_FOUND";
213         case STT_ERROR_OPERATION_FAILED:        return "STT_ERROR_OPERATION_FAILED";
214         case STT_ERROR_NOT_SUPPORTED_FEATURE:   return "STT_ERROR_NOT_SUPPORTED_FEATURE";
215         case STT_ERROR_SERVICE_RESET:           return "STT_ERROR_SERVICE_RESET";
216         default:
217                 return "Invalid error code";
218         }
219         //LCOV_EXCL_STOP
220 }
221
222 static int __stt_convert_config_error_code(stt_config_error_e code)
223 {
224         //LCOV_EXCL_START
225         if (code == STT_CONFIG_ERROR_NONE)                      return STT_ERROR_NONE;
226         if (code == STT_CONFIG_ERROR_OUT_OF_MEMORY)             return STT_ERROR_OUT_OF_MEMORY;
227         if (code == STT_CONFIG_ERROR_IO_ERROR)                  return STT_ERROR_IO_ERROR;
228         if (code == STT_CONFIG_ERROR_INVALID_PARAMETER)         return STT_ERROR_INVALID_PARAMETER;
229         if (code == STT_CONFIG_ERROR_PERMISSION_DENIED)         return STT_ERROR_PERMISSION_DENIED;
230         if (code == STT_CONFIG_ERROR_NOT_SUPPORTED)             return STT_ERROR_NOT_SUPPORTED;
231         if (code == STT_CONFIG_ERROR_INVALID_STATE)             return STT_ERROR_INVALID_STATE;
232         if (code == STT_CONFIG_ERROR_INVALID_LANGUAGE)          return STT_ERROR_INVALID_LANGUAGE;
233         if (code == STT_CONFIG_ERROR_ENGINE_NOT_FOUND)          return STT_ERROR_ENGINE_NOT_FOUND;
234         if (code == STT_CONFIG_ERROR_OPERATION_FAILED)          return STT_ERROR_OPERATION_FAILED;
235
236         return code;
237         //LCOV_EXCL_STOP
238 }
239
240 void __stt_config_lang_changed_cb(const char* before_language, const char* current_language, void* user_data)
241 {
242         SLOG(LOG_DEBUG, TAG_STTC, "Language changed : Before lang(%s) Current lang(%s)",
243                 before_language, current_language);
244
245         if (0 == strcmp(before_language, current_language)) {
246                 return;
247         }
248
249         GList* client_list = NULL;
250         client_list = stt_client_get_client_list();
251
252         GList *iter = NULL;
253         stt_client_s *data = NULL;
254
255         if (g_list_length(client_list) > 0) {
256                 /* Get a first item */
257                 iter = g_list_first(client_list);
258
259                 while (NULL != iter) {
260                         data = iter->data;
261                         if (NULL != data->default_lang_changed_cb) {
262                                 SLOG(LOG_DEBUG, TAG_STTC, "Call default language changed callback : uid(%d)", data->uid);
263                                 data->default_lang_changed_cb(data->stt, before_language, current_language,
264                                         data->default_lang_changed_user_data);
265                         }
266
267                         /* Next item */
268                         iter = g_list_next(iter);
269                 }
270         }
271
272         return;
273 }
274
275 static Eina_Bool __reconnect_by_engine_changed(void *data)
276 {
277         stt_h stt = (stt_h)data;
278
279         stt_client_s* client = stt_client_get(stt);
280         if (NULL == client) {
281                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
282                 return EINA_FALSE;
283         }
284
285         if (STT_STATE_READY != client->current_state) {
286                 usleep(10000);
287                 return EINA_TRUE;
288         }
289
290         int ret = stt_unprepare(stt);
291         if (0 != ret) {
292                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
293         }
294         ret = stt_prepare(stt);
295         if (0 != ret) {
296                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
297         }
298
299         return EINA_FALSE;
300 }
301
302 void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, bool support_silence, bool need_credential, void* user_data)
303 {
304         stt_h stt = (stt_h)user_data;
305
306         stt_client_s* client = stt_client_get(stt);
307         if (NULL == client) {
308                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
309                 return;
310         }
311
312         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_STTC, "Engine id(%s)", engine_id);
313         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_STTC, "Engine setting(%s)", setting);
314         if (NULL != language)   SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language);
315         SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need");
316
317         /* When the default engine is changed, please unload the old engine and load the new one. */
318         int ret = -1;
319
320         if (NULL == client->current_engine_id) {
321                 if (STT_STATE_RECORDING == client->current_state || STT_STATE_PROCESSING == client->current_state) {
322                         SLOG(LOG_INFO, TAG_STTC, "[INFO] stt cancel is invoked by engine_changed_cb, state(%d)", client->current_state);
323                         ret = stt_cancel(stt);
324                         if (0 != ret) {
325                                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] STT client cancelling...");
326                         }
327
328                         ecore_idler_add(__reconnect_by_engine_changed, (void*)stt);
329                 } else if (STT_STATE_READY == client->current_state) {
330                         ret = stt_unprepare(stt);
331                         if (0 != ret) {
332                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
333                         }
334                         ret = stt_prepare(stt);
335                         if (0 != ret) {
336                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
337                         }
338                 }
339         }
340
341         /* call callback function */
342         if (NULL != client->engine_changed_cb) {
343                 client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data);
344         } else {
345                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function for engine change");
346         }
347         return;
348 }
349
350 static int __stt_check_handle(stt_h stt, stt_client_s** client)
351 {
352         if (NULL == stt) {
353                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
354                 return STT_ERROR_INVALID_PARAMETER;
355         }
356
357         stt_client_s* temp = NULL;
358         temp = stt_client_get(stt);
359
360         /* check handle */
361         if (NULL == temp) {
362                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
363                 return STT_ERROR_INVALID_PARAMETER;
364         }
365         *client = temp;
366
367         return STT_ERROR_NONE;
368 }
369
370 int stt_create(stt_h* stt)
371 {
372         if (0 != __stt_get_feature_enabled()) {
373                 return STT_ERROR_NOT_SUPPORTED;
374         }
375         if (0 != __stt_check_privilege()) {
376                 return STT_ERROR_PERMISSION_DENIED;
377         }
378
379         SLOG(LOG_INFO, TAG_STTC, "===== Create STT");
380
381         if (NULL == stt) {
382                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
383                 return STT_ERROR_INVALID_PARAMETER;
384         }
385
386         if (0 == stt_client_get_size()) {
387                 if (0 != stt_dbus_open_connection()) {
388                         //LCOV_EXCL_START
389                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection");
390                         return STT_ERROR_OPERATION_FAILED;
391                         //LCOV_EXCL_STOP
392                 }
393         }
394
395         if (0 != stt_client_new(stt)) {
396                 //LCOV_EXCL_START
397                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!");
398                 return STT_ERROR_OUT_OF_MEMORY;
399                 //LCOV_EXCL_STOP
400         }
401
402         stt_client_s* client = stt_client_get(*stt);
403         if (NULL == client) {
404                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client"); //LCOV_EXCL_LINE
405                 stt_client_destroy(*stt);
406                 return STT_ERROR_OPERATION_FAILED;
407         }
408
409         int ret = stt_config_mgr_initialize(client->uid);
410         ret = __stt_convert_config_error_code(ret);
411         if (0 != ret) {
412                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to init config manager : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
413                 stt_client_destroy(*stt);
414                 return ret;
415         }
416
417         ret = stt_config_mgr_set_callback(client->uid, __stt_config_engine_changed_cb, __stt_config_lang_changed_cb, NULL, client->stt);
418         ret = __stt_convert_config_error_code(ret);
419         if (0 != ret) {
420                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set config changed : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
421                 stt_client_destroy(*stt);
422                 return ret;
423         }
424
425         SLOG(LOG_INFO, TAG_STTC, "[Success] uid(%d)", (*stt)->handle);
426
427         SLOG(LOG_DEBUG, TAG_STTC, "=====");
428         SLOG(LOG_DEBUG, TAG_STTC, " ");
429
430         return STT_ERROR_NONE;
431 }
432
433 int stt_destroy(stt_h stt)
434 {
435         stt_client_s* client = NULL;
436         if (0 != __stt_get_feature_enabled()) {
437                 return STT_ERROR_NOT_SUPPORTED;
438         }
439         if (0 != __stt_check_privilege()) {
440                 return STT_ERROR_PERMISSION_DENIED;
441         }
442         if (0 != __stt_check_handle(stt, &client)) {
443                 return STT_ERROR_INVALID_PARAMETER;
444         }
445
446         SLOG(LOG_INFO, TAG_STTC, "===== Destroy STT");
447
448         /* check used callback */
449         if (0 != stt_client_get_use_callback(client)) {
450                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Cannot destroy in Callback function");
451                 return STT_ERROR_OPERATION_FAILED;
452         }
453
454         stt_config_mgr_finalize(client->uid);
455
456         int ret = -1;
457
458         /* check state */
459         switch (client->current_state) {
460         case STT_STATE_PROCESSING:
461         case STT_STATE_RECORDING:
462         case STT_STATE_READY:
463                 ret = stt_dbus_request_finalize(client->uid);
464                 if (0 != ret) {
465                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
466                 }
467         case STT_STATE_CREATED:
468                 if (NULL != g_connect_timer) {
469                         SLOG(LOG_DEBUG, TAG_STTC, "Connect Timer is deleted");
470                         ecore_timer_del(g_connect_timer);
471                         g_connect_timer = NULL;
472                 }
473
474                 /* Free resources */
475                 stt_client_destroy(stt);
476                 break;
477         default:
478                 break;
479         }
480
481         if (0 == stt_client_get_size()) {
482                 if (0 != stt_dbus_close_connection()) {
483                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection"); //LCOV_EXCL_LINE
484                 }
485         }
486
487         stt = NULL;
488
489         SLOG(LOG_INFO, TAG_STTC, "=====");
490         SLOG(LOG_DEBUG, TAG_STTC, " ");
491
492         return STT_ERROR_NONE;
493 }
494
495 bool __stt_config_supported_engine_cb(const char* engine_id, const char* engine_name,
496                                       const char* setting, bool support_silence, void* user_data)
497 {
498         stt_h stt = (stt_h)user_data;
499
500         stt_client_s* client = stt_client_get(stt);
501         if (NULL == client) {
502                 //LCOV_EXCL_START
503                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
504                 return false;
505                 //LCOV_EXCL_STOP
506         }
507
508         /* call callback function */
509         if (NULL != client->supported_engine_cb) {
510                 return client->supported_engine_cb(stt, engine_id, engine_name, client->supported_engine_user_data);
511         } else {
512                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported engine"); //LCOV_EXCL_LINE
513         }
514
515         return false;
516 }
517
518 int stt_foreach_supported_engines(stt_h stt, stt_supported_engine_cb callback, void* user_data)
519 {
520         stt_client_s* client = NULL;
521         if (0 != __stt_get_feature_enabled()) {
522                 return STT_ERROR_NOT_SUPPORTED;
523         }
524         if (0 != __stt_check_privilege()) {
525                 return STT_ERROR_PERMISSION_DENIED;
526         }
527         if (0 != __stt_check_handle(stt, &client)) {
528                 return STT_ERROR_INVALID_PARAMETER;
529         }
530
531         SLOG(LOG_INFO, TAG_STTC, "===== Foreach Supported engine");
532
533         if (NULL == callback) {
534                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
535                 return STT_ERROR_INVALID_PARAMETER;
536         }
537
538         if (client->current_state != STT_STATE_CREATED) {
539                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
540                 return STT_ERROR_INVALID_STATE;
541         }
542
543         client->supported_engine_cb = callback;
544         client->supported_engine_user_data = user_data;
545
546         int ret = 0;
547         ret = stt_config_mgr_get_engine_list(__stt_config_supported_engine_cb, client->stt);
548         ret = __stt_convert_config_error_code(ret);
549         if (0 != ret) {
550                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get engines : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
551         }
552
553         client->supported_engine_cb = NULL;
554         client->supported_engine_user_data = NULL;
555
556         SLOG(LOG_INFO, TAG_STTC, "=====");
557         SLOG(LOG_DEBUG, TAG_STTC, " ");
558
559         return ret;
560 }
561
562 int stt_get_engine(stt_h stt, char** engine_id)
563 {
564         stt_client_s* client = NULL;
565         if (0 != __stt_get_feature_enabled()) {
566                 return STT_ERROR_NOT_SUPPORTED;
567         }
568         if (0 != __stt_check_privilege()) {
569                 return STT_ERROR_PERMISSION_DENIED;
570         }
571         if (0 != __stt_check_handle(stt, &client)) {
572                 return STT_ERROR_INVALID_PARAMETER;
573         }
574
575         SLOG(LOG_INFO, TAG_STTC, "===== Get current engine");
576
577         if (NULL == engine_id) {
578                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
579                 return STT_ERROR_INVALID_PARAMETER;
580         }
581
582         if (client->current_state != STT_STATE_CREATED) {
583                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
584                 return STT_ERROR_INVALID_STATE;
585         }
586
587         int ret = 0;
588
589         if (NULL != client->current_engine_id) {
590                 *engine_id = strdup(client->current_engine_id);
591                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
592         } else {
593
594                 ret = stt_config_mgr_get_engine(engine_id);
595                 ret = __stt_convert_config_error_code(ret);
596                 if (0 != ret) {
597                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request get current engine : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
598                 } else {
599                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
600                 }
601         }
602
603         SLOG(LOG_INFO, TAG_STTC, "=====");
604         SLOG(LOG_DEBUG, TAG_STTC, " ");
605
606         return ret;
607 }
608
609 int __stt_set_buxtonkey(const char* engine_id)
610 {
611         /* Set vconfkey */
612         struct buxton_client * bux_cli;
613         struct buxton_layer * bux_layer;
614         struct buxton_value * bux_val;
615
616         int ret = buxton_open(&bux_cli, NULL, NULL);
617         if (0 != ret) {
618                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to open buxton client"); //LCOV_EXCL_LINE
619                 return STT_ERROR_OPERATION_FAILED;
620         }
621         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_open: %d", ret);
622         bux_layer = buxton_create_layer("system");
623         if (NULL == bux_layer) {
624                 //LCOV_EXCL_START
625                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL");
626                 buxton_close(bux_cli);
627                 bux_cli = NULL;
628                 return STT_ERROR_OPERATION_FAILED;
629                 //LCOV_EXCL_STOP
630         }
631         bux_val = buxton_value_create_string(engine_id);
632         if (NULL == bux_val) {
633                 //LCOV_EXCL_START
634                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL");
635                 buxton_free_layer(bux_layer);
636                 buxton_close(bux_cli);
637                 bux_layer = NULL;
638                 bux_cli = NULL;
639                 return STT_ERROR_OPERATION_FAILED;
640                 //LCOV_EXCL_STOP
641         }
642
643         ret = buxton_set_value_sync(bux_cli, bux_layer, STT_ENGINE_DB_CUSTOM, bux_val);
644         if (0 != ret) {
645                 //LCOV_EXCL_START
646                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to set value sync");
647                 buxton_value_free(bux_val);
648                 buxton_free_layer(bux_layer);
649                 buxton_close(bux_cli);
650
651                 bux_cli = NULL;
652                 bux_layer = NULL;
653                 bux_val = NULL;
654                 return STT_ERROR_OPERATION_FAILED;
655                 //LCOV_EXCL_STOP
656         }
657         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %d, %s", ret, STT_ENGINE_DB_CUSTOM);
658
659         buxton_value_free(bux_val);
660         buxton_free_layer(bux_layer);
661         buxton_close(bux_cli);
662
663         bux_cli = NULL;
664         bux_layer = NULL;
665         bux_val = NULL;
666
667         return STT_ERROR_NONE;
668 }
669
670 int stt_set_engine(stt_h stt, const char* engine_id)
671 {
672         stt_client_s* client = NULL;
673         if (0 != __stt_get_feature_enabled()) {
674                 return STT_ERROR_NOT_SUPPORTED;
675         }
676         if (0 != __stt_check_privilege()) {
677                 return STT_ERROR_PERMISSION_DENIED;
678         }
679         if (0 != __stt_check_privilege_for_applaunch()) {
680                 return STT_ERROR_PERMISSION_DENIED;
681         }
682         if (0 != __stt_check_handle(stt, &client)) {
683                 return STT_ERROR_INVALID_PARAMETER;
684         }
685
686         SLOG(LOG_INFO, TAG_STTC, "===== Set current engine");
687
688         if (NULL == engine_id) {
689                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
690                 return STT_ERROR_INVALID_PARAMETER;
691         }
692
693         /* check state */
694         if (client->current_state != STT_STATE_CREATED) {
695                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
696                 return STT_ERROR_INVALID_STATE;
697         }
698
699         if (NULL != client->current_engine_id) {
700                 free(client->current_engine_id);
701                 client->current_engine_id = NULL;
702         }
703
704         SLOG(LOG_INFO, TAG_STTC, "===== engined_id(%s)", engine_id);
705
706         client->current_engine_id = strdup(engine_id);
707
708         /* Set vconfkey */
709         int ret = __stt_set_buxtonkey(engine_id);
710         if (0 != ret) {
711                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] set buxtonkey Failed!!!"); //LCOV_EXCL_LINE
712                 return ret;
713         }
714
715         SLOG(LOG_INFO, TAG_STTC, "=====");
716         SLOG(LOG_DEBUG, TAG_STTC, " ");
717
718         return 0;
719 }
720
721 int stt_set_credential(stt_h stt, const char* credential)
722 {
723         stt_client_s* client = NULL;
724         if (0 != __stt_get_feature_enabled()) {
725                 return STT_ERROR_NOT_SUPPORTED;
726         }
727         if (0 != __stt_check_privilege()) {
728                 return STT_ERROR_PERMISSION_DENIED;
729         }
730         if (0 != __stt_check_handle(stt, &client)) {
731                 return STT_ERROR_INVALID_PARAMETER;
732         }
733
734         SLOG(LOG_INFO, TAG_STTC, "===== Set credential");
735
736         if (NULL == credential) {
737                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
738                 return STT_ERROR_INVALID_PARAMETER;
739         }
740
741         /* check state */
742         if (client->current_state != STT_STATE_CREATED && client->current_state != STT_STATE_READY) {
743                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED or READY", client->current_state); //LCOV_EXCL_LINE
744                 return STT_ERROR_INVALID_STATE;
745         }
746
747         if (NULL != client->credential) {
748                 free(client->credential);
749                 client->credential = NULL;
750         }
751         client->credential = strdup(credential);
752
753         SLOG(LOG_INFO, TAG_STTC, "=====");
754         SLOG(LOG_DEBUG, TAG_STTC, " ");
755
756         return STT_ERROR_NONE;
757 }
758
759 int stt_set_private_data(stt_h stt, const char* key, const char* data)
760 {
761         stt_client_s* client = NULL;
762         if (0 != __stt_get_feature_enabled()) {
763                 return STT_ERROR_NOT_SUPPORTED;
764         }
765         if (0 != __stt_check_privilege()) {
766                 return STT_ERROR_PERMISSION_DENIED;
767         }
768         if (0 != __stt_check_handle(stt, &client)) {
769                 return STT_ERROR_INVALID_PARAMETER;
770         }
771
772         SLOG(LOG_INFO, TAG_STTC, "===== Set private data");
773
774         if (NULL == key || NULL == data) {
775                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
776                 return STT_ERROR_INVALID_PARAMETER;
777         }
778
779         /* check state */
780         if (STT_STATE_READY != client->current_state) {
781                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
782                 return STT_ERROR_INVALID_STATE;
783         }
784
785         if (true != client->internal && (0 == strcmp(key, "server") || 0 == strcmp(key, "rampcode") || 0 == strcmp(key, "epd"))) {
786                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This is not an internal app"); //LCOV_EXCL_LINE
787                 return STT_ERROR_INVALID_PARAMETER;
788         }
789
790         int ret = -1;
791         int count = 0;
792         while (0 != ret) {
793                 ret = stt_dbus_request_set_private_data(client->uid, key, data);
794                 if (0 != ret) {
795                         //LCOV_EXCL_START
796                         if (STT_ERROR_TIMED_OUT != ret) {
797                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data : %s", __stt_get_error_code(ret));
798                                 return ret;
799                         } else {
800                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
801                                 usleep(10000);
802                                 count++;
803                                 if (STT_RETRY_COUNT == count) {
804                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
805                                         return ret;
806                                 }
807                         }
808                         //LCOV_EXCL_STOP
809                 }
810         }
811
812         SLOG(LOG_INFO, TAG_STTC, "=====");
813         SLOG(LOG_DEBUG, TAG_STTC, "");
814
815         return STT_ERROR_NONE;
816
817 }
818 int stt_get_private_data(stt_h stt, const char* key, char** data)
819 {
820         stt_client_s* client = NULL;
821         if (0 != __stt_get_feature_enabled()) {
822                 return STT_ERROR_NOT_SUPPORTED;
823         }
824         if (0 != __stt_check_privilege()) {
825                 return STT_ERROR_PERMISSION_DENIED;
826         }
827         if (0 != __stt_check_handle(stt, &client)) {
828                 return STT_ERROR_INVALID_PARAMETER;
829         }
830
831         SLOG(LOG_INFO, TAG_STTC, "===== Get private data");
832
833         if (NULL == key || NULL == data) {
834                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
835                 return STT_ERROR_INVALID_PARAMETER;
836         }
837
838         /* check state */
839         if (STT_STATE_READY != client->current_state) {
840                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
841                 return STT_ERROR_INVALID_STATE;
842         }
843
844         int ret = -1;
845         int count = 0;
846         while (0 != ret) {
847                 ret = stt_dbus_request_get_private_data(client->uid, key, data);
848                 if (0 != ret) {
849                         //LCOV_EXCL_START
850                         if (STT_ERROR_TIMED_OUT != ret) {
851                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get private data : %s", __stt_get_error_code(ret));
852                                 return ret;
853                         } else {
854                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
855                                 usleep(10000);
856                                 count++;
857                                 if (STT_RETRY_COUNT == count) {
858                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
859                                         return ret;
860                                 }
861                         }
862                         //LCOV_EXCL_STOP
863                 }
864         }
865
866         if (0 == strncmp(*data, "NULL", strlen(*data))) {
867                 free(*data);
868                 *data = NULL;
869         }
870
871         SLOG(LOG_INFO, TAG_STTC, "=====");
872         SLOG(LOG_DEBUG, TAG_STTC, "");
873
874         return STT_ERROR_NONE;
875 }
876
877 //LCOV_EXCL_START
878 int stt_set_server_stt(stt_h stt, const char* key, char* user_data)
879 {
880         int ret = -1;
881         stt_client_s* client = NULL;
882
883         if (0 != __stt_get_feature_enabled()) {
884                 return STT_ERROR_NOT_SUPPORTED;
885         }
886         if (0 != __stt_check_privilege()) {
887                 return STT_ERROR_PERMISSION_DENIED;
888         }
889         if (0 != __stt_check_handle(stt, &client)) {
890                 return STT_ERROR_INVALID_PARAMETER;
891         }
892
893         SLOG(LOG_INFO, TAG_STTC, "===== Set STT server");
894
895         if (NULL == key || NULL == user_data) {
896                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
897                 return STT_ERROR_INVALID_PARAMETER;
898         }
899
900         if (STT_STATE_CREATED != client->current_state && STT_STATE_READY != client->current_state) {
901                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] The current state is invalid (%d).", client->current_state);
902                 return STT_ERROR_INVALID_STATE;
903         }
904
905
906         client->internal = true;
907
908         char* private_key = NULL;
909         private_key = strdup(key);
910         if (NULL == private_key) {
911                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(private_key)");
912                 return STT_ERROR_OUT_OF_MEMORY;
913         }
914
915         char* data = NULL;
916         data = strdup(user_data);
917         if (NULL == data) {
918                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(data)");
919                 free(private_key);
920                 private_key = NULL;
921                 return STT_ERROR_OUT_OF_MEMORY;
922         }
923
924         ret = stt_set_private_data(stt, private_key, data);
925         if (0 != ret) {
926                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data, ret(%d), key(%s)", ret, private_key);
927         }
928
929         free(data);
930         data = NULL;
931         free(private_key);
932         private_key = NULL;
933
934         SLOG(LOG_INFO, TAG_STTC, "======");
935         SLOG(LOG_DEBUG, TAG_STTC, " ");
936
937         return ret;
938 }
939 //LCOV_EXCL_STOP
940
941 static Eina_Bool __stt_connect_daemon(void *data)
942 {
943         stt_client_s* client = (stt_client_s*)data;
944         int ret = -1;
945
946         if (NULL == client) {
947                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE
948                 g_connect_timer = NULL;
949                 return EINA_FALSE;
950         }
951
952         if (0 == stt_client_get_size() || NULL == stt_client_get_by_uid(client->uid)) {
953                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Client has been already destroyed"); //LCOV_EXCL_LINE
954                 return EINA_FALSE;
955         }
956
957         /* Check and Set vconfkey of custom engine before sending hello */
958         if (1 == g_privilege_applaunch_allowed && NULL != client->current_engine_id) {
959                 /* Set vconfkey */
960                 ret = __stt_set_buxtonkey(client->current_engine_id);
961                 //LCOV_EXCL_START
962                 if (0 != ret) {
963                         SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] set buxtonkey Failed!!! (inside __stt_connect_daemon)");
964                         return EINA_TRUE;
965                 }
966                 //LCOV_EXCL_STOP
967         }
968
969         /* Send hello */
970         ret = stt_dbus_request_hello(client->uid);
971
972         if (0 != ret) {
973                 if (STT_ERROR_INVALID_STATE == ret) {
974                         g_connect_timer = NULL;
975                         return EINA_FALSE;
976                 }
977                 return EINA_TRUE;
978         }
979
980         g_connect_timer = NULL;
981         SLOG(LOG_INFO, TAG_STTC, "===== Connect stt-service");
982
983         /* request initialization */
984         bool silence_supported = false;
985         bool credential_needed = false;
986
987         ret = stt_dbus_request_initialize(client->uid, &silence_supported, &credential_needed);
988
989         if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
990                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
991
992                 client->reason = STT_ERROR_ENGINE_NOT_FOUND;
993                 ecore_main_loop_thread_safe_call_async(__stt_notify_error, (void*)client);
994
995                 return EINA_FALSE;
996
997         } else if (STT_ERROR_NONE != ret) {
998                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] Fail to connection. Retry to connect"); //LCOV_EXCL_LINE
999                 return EINA_TRUE;
1000         } else {
1001                 /* success to connect stt-service */
1002                 client->silence_supported = silence_supported;
1003                 client->credential_needed = credential_needed;
1004                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
1005         }
1006
1007 //LCOV_EXCL_START
1008 #ifdef __UNUSED_CODES__
1009         if (NULL != client->current_engine_id) {
1010                 ret = -1;
1011                 int count = 0;
1012                 silence_supported = false;
1013                 credential_needed = false;
1014                 SLOG(LOG_DEBUG, TAG_STTC, "[WARNING] current_engine_id(%s)", client->current_engine_id);
1015
1016                 while (0 != ret) {
1017                         ret = stt_dbus_request_set_current_engine(client->uid, client->current_engine_id, &silence_supported, &credential_needed);
1018                         if (0 != ret) {
1019                                 if (STT_ERROR_TIMED_OUT != ret) {
1020                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set current engine : %s", __stt_get_error_code(ret));
1021                                         return ret;
1022                                 } else {
1023                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1024                                         usleep(10000);
1025                                         count++;
1026                                         if (STT_RETRY_COUNT == count) {
1027                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1028                                                 return ret;
1029                                         }
1030                                 }
1031                         } else {
1032                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", client->current_engine_id);
1033
1034                                 /* success to change engine */
1035                                 client->silence_supported = silence_supported;
1036                                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
1037                         }
1038                 }
1039         }
1040 #endif
1041 //LCOV_EXCL_STOP
1042         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] uid(%d)", client->uid);
1043
1044         client->before_state = client->current_state;
1045         client->current_state = STT_STATE_READY;
1046
1047         if (NULL != client->state_changed_cb) {
1048                 stt_client_use_callback(client);
1049                 client->state_changed_cb(client->stt, client->before_state,
1050                         client->current_state, client->state_changed_user_data);
1051                 stt_client_not_use_callback(client);
1052                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1053         } else {
1054                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1055         }
1056
1057         SLOG(LOG_INFO, TAG_STTC, "=====");
1058         SLOG(LOG_DEBUG, TAG_STTC, "  ");
1059
1060         return EINA_FALSE;
1061 }
1062
1063 int stt_prepare(stt_h stt)
1064 {
1065         stt_client_s* client = NULL;
1066         if (0 != __stt_get_feature_enabled()) {
1067                 return STT_ERROR_NOT_SUPPORTED;
1068         }
1069         if (0 != __stt_check_privilege()) {
1070                 return STT_ERROR_PERMISSION_DENIED;
1071         }
1072         if (0 != __stt_check_handle(stt, &client)) {
1073                 return STT_ERROR_INVALID_PARAMETER;
1074         }
1075
1076         SLOG(LOG_INFO, TAG_STTC, "===== Prepare STT");
1077
1078         /* check state */
1079         if (client->current_state != STT_STATE_CREATED) {
1080                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'CREATED'", client->current_state);
1081                 return STT_ERROR_INVALID_STATE;
1082         }
1083
1084         ecore_thread_main_loop_begin();
1085         g_connect_timer = ecore_timer_add(0.02, __stt_connect_daemon, (void*)client);
1086         ecore_thread_main_loop_end();
1087
1088         SLOG(LOG_INFO, TAG_STTC, "=====");
1089         SLOG(LOG_DEBUG, TAG_STTC, " ");
1090
1091         return STT_ERROR_NONE;
1092 }
1093
1094 int stt_unprepare(stt_h stt)
1095 {
1096         stt_client_s* client = NULL;
1097         if (0 != __stt_get_feature_enabled()) {
1098                 return STT_ERROR_NOT_SUPPORTED;
1099         }
1100         if (0 != __stt_check_privilege()) {
1101                 return STT_ERROR_PERMISSION_DENIED;
1102         }
1103         if (0 != __stt_check_handle(stt, &client)) {
1104                 return STT_ERROR_INVALID_PARAMETER;
1105         }
1106
1107         SLOG(LOG_INFO, TAG_STTC, "===== Unprepare STT");
1108
1109         /* check state */
1110         if (client->current_state != STT_STATE_READY) {
1111                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", client->current_state);
1112                 return STT_ERROR_INVALID_STATE;
1113         }
1114
1115         int ret = -1;
1116         int count = 0;
1117         while (0 != ret) {
1118                 ret = stt_dbus_request_finalize(client->uid);
1119                 if (0 != ret) {
1120                         //LCOV_EXCL_START
1121                         if (STT_ERROR_TIMED_OUT != ret) {
1122                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
1123                                 break;
1124                         } else {
1125                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1126                                 usleep(10000);
1127                                 count++;
1128                                 if (STT_RETRY_COUNT == count) {
1129                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1130                                         break;
1131                                 }
1132                         }
1133                         //LCOV_EXCL_STOP
1134                 }
1135         }
1136
1137         client->internal_state = STT_INTERNAL_STATE_NONE;
1138
1139         client->before_state = client->current_state;
1140         client->current_state = STT_STATE_CREATED;
1141
1142         if (NULL != client->state_changed_cb) {
1143                 stt_client_use_callback(client);
1144                 client->state_changed_cb(client->stt, client->before_state,
1145                         client->current_state, client->state_changed_user_data);
1146                 stt_client_not_use_callback(client);
1147         } else {
1148                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1149         }
1150
1151         if (g_connect_timer) {
1152                 ecore_timer_del(g_connect_timer);
1153                 g_connect_timer = NULL;
1154         }
1155
1156         SLOG(LOG_INFO, TAG_STTC, "=====");
1157         SLOG(LOG_DEBUG, TAG_STTC, " ");
1158
1159         return STT_ERROR_NONE;
1160 }
1161
1162 bool __stt_config_supported_language_cb(const char* engine_id, const char* language, void* user_data)
1163 {
1164         stt_h stt = (stt_h)user_data;
1165
1166         stt_client_s* client = stt_client_get(stt);
1167         if (NULL == client) {
1168                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid"); //LCOV_EXCL_LINE
1169                 return false;
1170         }
1171
1172         SLOG(LOG_INFO, TAG_STTC, "===== supported language callback");
1173
1174         /* call callback function */
1175         if (NULL != client->supported_lang_cb) {
1176                 return client->supported_lang_cb(stt, language, client->supported_lang_user_data);
1177         } else {
1178                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported languages"); //LCOV_EXCL_LINE
1179         }
1180
1181         return false;
1182 }
1183
1184 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
1185 {
1186         stt_client_s* client = NULL;
1187         if (0 != __stt_get_feature_enabled()) {
1188                 return STT_ERROR_NOT_SUPPORTED;
1189         }
1190         if (0 != __stt_check_privilege()) {
1191                 return STT_ERROR_PERMISSION_DENIED;
1192         }
1193         if (0 != __stt_check_handle(stt, &client)) {
1194                 return STT_ERROR_INVALID_PARAMETER;
1195         }
1196
1197         SLOG(LOG_INFO, TAG_STTC, "===== Foreach Supported Language");
1198
1199         if (NULL == callback) {
1200                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1201                 return STT_ERROR_INVALID_PARAMETER;
1202         }
1203
1204         int ret;
1205         char* current_engine_id = NULL;
1206
1207         if (NULL == client->current_engine_id) {
1208                 ret = stt_config_mgr_get_engine(&current_engine_id);
1209                 ret = __stt_convert_config_error_code(ret);
1210                 if (0 != ret) {
1211                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default engine id : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1212                         return ret;
1213                 }
1214         } else {
1215                 current_engine_id = strdup(client->current_engine_id);
1216                 //LCOV_EXCL_START
1217                 if (NULL == current_engine_id) {
1218                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1219                         return STT_ERROR_OUT_OF_MEMORY;
1220                 }
1221                 //LCOV_EXCL_STOP
1222         }
1223
1224         client->supported_lang_cb = callback;
1225         client->supported_lang_user_data = user_data;
1226
1227         ret = stt_config_mgr_get_language_list(current_engine_id, __stt_config_supported_language_cb, client->stt);
1228         ret = __stt_convert_config_error_code(ret);
1229         if (0 != ret) {
1230                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1231         }
1232
1233         if (NULL != current_engine_id) {
1234                 free(current_engine_id);
1235                 current_engine_id = NULL;
1236         }
1237
1238         client->supported_lang_cb = NULL;
1239         client->supported_lang_user_data = NULL;
1240
1241         SLOG(LOG_INFO, TAG_STTC, "=====");
1242         SLOG(LOG_DEBUG, TAG_STTC, " ");
1243
1244         return ret;
1245 }
1246
1247 int stt_get_default_language(stt_h stt, char** language)
1248 {
1249         stt_client_s* client = NULL;
1250         if (0 != __stt_get_feature_enabled()) {
1251                 return STT_ERROR_NOT_SUPPORTED;
1252         }
1253         if (0 != __stt_check_privilege()) {
1254                 return STT_ERROR_PERMISSION_DENIED;
1255         }
1256         if (0 != __stt_check_handle(stt, &client)) {
1257                 return STT_ERROR_INVALID_PARAMETER;
1258         }
1259
1260         SLOG(LOG_INFO, TAG_STTC, "===== Get Default Language");
1261
1262         if (NULL == language) {
1263                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1264                 return STT_ERROR_INVALID_PARAMETER;
1265         }
1266
1267         int ret = 0;
1268         ret = stt_config_mgr_get_default_language(language);
1269         ret = __stt_convert_config_error_code(ret);
1270         if (0 != ret) {
1271                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default language : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1272         } else {
1273                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
1274         }
1275
1276         SLOG(LOG_INFO, TAG_STTC, "=====");
1277         SLOG(LOG_DEBUG, TAG_STTC, " ");
1278
1279         return ret;
1280 }
1281
1282 int stt_get_state(stt_h stt, stt_state_e* state)
1283 {
1284         stt_client_s* client = NULL;
1285         if (0 != __stt_get_feature_enabled()) {
1286                 return STT_ERROR_NOT_SUPPORTED;
1287         }
1288         if (0 != __stt_check_privilege()) {
1289                 return STT_ERROR_PERMISSION_DENIED;
1290         }
1291         if (0 != __stt_check_handle(stt, &client)) {
1292                 return STT_ERROR_INVALID_PARAMETER;
1293         }
1294
1295         if (NULL == state) {
1296                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1297                 return STT_ERROR_INVALID_PARAMETER;
1298         }
1299
1300         *state = client->current_state;
1301
1302         SLOG(LOG_INFO, TAG_STTC, "===== Get state(%d)", *state);
1303
1304         switch (*state) {
1305         case STT_STATE_CREATED:         SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'");        break;
1306         case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
1307         case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
1308         case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
1309         default:                        SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid value");             break;
1310         }
1311
1312         return STT_ERROR_NONE;
1313 }
1314
1315 int stt_get_error_message(stt_h stt, char** err_msg)
1316 {
1317         stt_client_s* client = NULL;
1318         if (0 != __stt_get_feature_enabled()) {
1319                 return STT_ERROR_NOT_SUPPORTED;
1320         }
1321         if (0 != __stt_check_privilege()) {
1322                 return STT_ERROR_PERMISSION_DENIED;
1323         }
1324         if (0 != __stt_check_handle(stt, &client)) {
1325                 return STT_ERROR_INVALID_PARAMETER;
1326         }
1327
1328         if (NULL == err_msg) {
1329                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1330                 return STT_ERROR_INVALID_PARAMETER;
1331         }
1332
1333         if (false == g_err_callback_status) {
1334                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This callback should be called during an err_callback");
1335                 return STT_ERROR_OPERATION_FAILED;
1336         }
1337
1338         if (NULL != client->err_msg) {
1339                 *err_msg = strdup(client->err_msg);
1340                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (%s)", *err_msg); //LCOV_EXCL_LINE
1341         } else {
1342                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (NULL)"); //LCOV_EXCL_LINE
1343         }
1344
1345         SLOG(LOG_INFO, TAG_STTC, "====="); //LCOV_EXCL_LINE
1346         SLOG(LOG_DEBUG, TAG_STTC, " "); //LCOV_EXCL_LINE
1347
1348         return STT_ERROR_NONE;
1349 }
1350
1351 int stt_is_recognition_type_supported(stt_h stt, const char* type, bool* support)
1352 {
1353         stt_client_s* client = NULL;
1354         if (0 != __stt_get_feature_enabled()) {
1355                 return STT_ERROR_NOT_SUPPORTED;
1356         }
1357         if (0 != __stt_check_privilege()) {
1358                 return STT_ERROR_PERMISSION_DENIED;
1359         }
1360         if (0 != __stt_check_handle(stt, &client)) {
1361                 return STT_ERROR_INVALID_PARAMETER;
1362         }
1363
1364         if (NULL == type || NULL == support) {
1365                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1366                 return STT_ERROR_INVALID_PARAMETER;
1367         }
1368
1369         /* check state */
1370         if (client->current_state != STT_STATE_READY) {
1371                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1372                 return STT_ERROR_INVALID_STATE;
1373         }
1374
1375         int ret = -1;
1376         int count = 0;
1377         while (0 != ret) {
1378                 ret = stt_dbus_request_is_recognition_type_supported(client->uid, type, support);
1379                 if (0 != ret) {
1380                         //LCOV_EXCL_START
1381                         if (STT_ERROR_TIMED_OUT != ret) {
1382                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get recognition type supported : %s", __stt_get_error_code(ret));
1383                                 return ret;
1384                         } else {
1385                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1386                                 usleep(10000);
1387                                 count++;
1388                                 if (STT_RETRY_COUNT == count) {
1389                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1390                                         return ret;
1391                                 }
1392                         }
1393                         //LCOV_EXCL_STOP
1394                 } else {
1395                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] recognition type is %s", *support ? "true " : "false");
1396                         break;
1397                 }
1398         }
1399
1400         return STT_ERROR_NONE;
1401 }
1402
1403 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
1404 {
1405         stt_client_s* client = NULL;
1406         if (0 != __stt_get_feature_enabled()) {
1407                 return STT_ERROR_NOT_SUPPORTED;
1408         }
1409         if (0 != __stt_check_privilege()) {
1410                 return STT_ERROR_PERMISSION_DENIED;
1411         }
1412         if (0 != __stt_check_handle(stt, &client)) {
1413                 return STT_ERROR_INVALID_PARAMETER;
1414         }
1415
1416         /* check state */
1417         if (client->current_state != STT_STATE_READY) {
1418                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1419                 return STT_ERROR_INVALID_STATE;
1420         }
1421
1422         SLOG(LOG_INFO, TAG_STTC, "===== Set silence detection, supported(%d), type(%d)", client->silence_supported, type);
1423
1424         if (true == client->silence_supported) {
1425                 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO) {
1426                         client->silence = type;
1427                 } else {
1428                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
1429                         return STT_ERROR_INVALID_PARAMETER;
1430                 }
1431         } else {
1432                 return STT_ERROR_NOT_SUPPORTED_FEATURE;
1433         }
1434
1435         return STT_ERROR_NONE;
1436 }
1437
1438 int stt_set_start_sound(stt_h stt, const char* filename)
1439 {
1440         stt_client_s* client = NULL;
1441         if (0 != __stt_get_feature_enabled()) {
1442                 return STT_ERROR_NOT_SUPPORTED;
1443         }
1444         if (0 != __stt_check_privilege()) {
1445                 return STT_ERROR_PERMISSION_DENIED;
1446         }
1447         if (0 != __stt_check_handle(stt, &client)) {
1448                 return STT_ERROR_INVALID_PARAMETER;
1449         }
1450
1451         SLOG(LOG_INFO, TAG_STTC, "===== STT SET START SOUND");
1452
1453         if (NULL == filename) {
1454                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1455                 return STT_ERROR_INVALID_PARAMETER;
1456         }
1457
1458         if (0 != access(filename, F_OK)) {
1459                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1460                 return STT_ERROR_INVALID_PARAMETER;
1461         }
1462
1463         /* check state */
1464         if (client->current_state != STT_STATE_READY) {
1465                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1466                 return STT_ERROR_INVALID_STATE;
1467         }
1468
1469         int ret = -1;
1470         int count = 0;
1471         while (0 != ret) {
1472                 ret = stt_dbus_request_set_start_sound(client->uid, filename);
1473                 if (0 != ret) {
1474                         //LCOV_EXCL_START
1475                         if (STT_ERROR_TIMED_OUT != ret) {
1476                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set start sound : %s", __stt_get_error_code(ret));
1477                                 return ret;
1478                         } else {
1479                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1480                                 usleep(10000);
1481                                 count++;
1482                                 if (STT_RETRY_COUNT == count) {
1483                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1484                                         return ret;
1485                                 }
1486                         }
1487                         //LCOV_EXCL_STOP
1488                 } else {
1489                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set start sound : %s", filename);
1490                         break;
1491                 }
1492         }
1493
1494         return STT_ERROR_NONE;
1495 }
1496
1497 int stt_unset_start_sound(stt_h stt)
1498 {
1499         stt_client_s* client = NULL;
1500         if (0 != __stt_get_feature_enabled()) {
1501                 return STT_ERROR_NOT_SUPPORTED;
1502         }
1503         if (0 != __stt_check_privilege()) {
1504                 return STT_ERROR_PERMISSION_DENIED;
1505         }
1506         if (0 != __stt_check_handle(stt, &client)) {
1507                 return STT_ERROR_INVALID_PARAMETER;
1508         }
1509
1510         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET START SOUND");
1511
1512         /* check state */
1513         if (client->current_state != STT_STATE_READY) {
1514                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1515                 return STT_ERROR_INVALID_STATE;
1516         }
1517
1518         int ret = -1;
1519         int count = 0;
1520         while (0 != ret) {
1521                 ret = stt_dbus_request_unset_start_sound(client->uid);
1522                 if (0 != ret) {
1523                         //LCOV_EXCL_START
1524                         if (STT_ERROR_TIMED_OUT != ret) {
1525                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset start sound : %s", __stt_get_error_code(ret));
1526                                 return ret;
1527                         } else {
1528                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1529                                 usleep(10000);
1530                                 count++;
1531                                 if (STT_RETRY_COUNT == count) {
1532                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1533                                         return ret;
1534                                 }
1535                         }
1536                         //LCOV_EXCL_STOP
1537                 } else {
1538                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset start sound");
1539                         break;
1540                 }
1541         }
1542
1543         return STT_ERROR_NONE;
1544 }
1545
1546 int stt_set_stop_sound(stt_h stt, const char* filename)
1547 {
1548         stt_client_s* client = NULL;
1549         if (0 != __stt_get_feature_enabled()) {
1550                 return STT_ERROR_NOT_SUPPORTED;
1551         }
1552         if (0 != __stt_check_privilege()) {
1553                 return STT_ERROR_PERMISSION_DENIED;
1554         }
1555         if (0 != __stt_check_handle(stt, &client)) {
1556                 return STT_ERROR_INVALID_PARAMETER;
1557         }
1558
1559         SLOG(LOG_INFO, TAG_STTC, "===== STT SET STOP SOUND");
1560
1561         if (NULL == filename) {
1562                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1563                 return STT_ERROR_INVALID_PARAMETER;
1564         }
1565
1566         if (0 != access(filename, F_OK)) {
1567                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1568                 return STT_ERROR_INVALID_PARAMETER;
1569         }
1570
1571         /* check state */
1572         if (client->current_state != STT_STATE_READY) {
1573                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1574                 return STT_ERROR_INVALID_STATE;
1575         }
1576
1577         int ret = -1;
1578         int count = 0;
1579         while (0 != ret) {
1580                 ret = stt_dbus_request_set_stop_sound(client->uid, filename);
1581                 if (0 != ret) {
1582                         //LCOV_EXCL_START
1583                         if (STT_ERROR_TIMED_OUT != ret) {
1584                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set stop sound : %s", __stt_get_error_code(ret));
1585                                 return ret;
1586                         } else {
1587                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1588                                 usleep(10000);
1589                                 count++;
1590                                 if (STT_RETRY_COUNT == count) {
1591                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1592                                         return ret;
1593                                 }
1594                         }
1595                         //LCOV_EXCL_STOP
1596                 } else {
1597                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set stop sound : %s", filename);
1598                         break;
1599                 }
1600         }
1601
1602         return STT_ERROR_NONE;
1603 }
1604
1605 int stt_unset_stop_sound(stt_h stt)
1606 {
1607         stt_client_s* client = NULL;
1608         if (0 != __stt_get_feature_enabled()) {
1609                 return STT_ERROR_NOT_SUPPORTED;
1610         }
1611         if (0 != __stt_check_privilege()) {
1612                 return STT_ERROR_PERMISSION_DENIED;
1613         }
1614         if (0 != __stt_check_handle(stt, &client)) {
1615                 return STT_ERROR_INVALID_PARAMETER;
1616         }
1617
1618         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET STOP SOUND");
1619
1620         /* check state */
1621         if (client->current_state != STT_STATE_READY) {
1622                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1623                 return STT_ERROR_INVALID_STATE;
1624         }
1625
1626         int ret = -1;
1627         int count = 0;
1628         while (0 != ret) {
1629                 ret = stt_dbus_request_unset_stop_sound(client->uid);
1630                 if (0 != ret) {
1631                         //LCOV_EXCL_START
1632                         if (STT_ERROR_TIMED_OUT != ret) {
1633                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset stop sound : %s", __stt_get_error_code(ret));
1634                                 return ret;
1635                         } else {
1636                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1637                                 usleep(10000);
1638                                 count++;
1639                                 if (STT_RETRY_COUNT == count) {
1640                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1641                                         return ret;
1642                                 }
1643                         }
1644                         //LCOV_EXCL_STOP
1645                 } else {
1646                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset stop sound");
1647                         break;
1648                 }
1649         }
1650
1651         return STT_ERROR_NONE;
1652 }
1653
1654 int stt_start(stt_h stt, const char* language, const char* type)
1655 {
1656         stt_client_s* client = NULL;
1657         if (0 != __stt_get_feature_enabled()) {
1658                 return STT_ERROR_NOT_SUPPORTED;
1659         }
1660         if (0 != __stt_check_privilege()) {
1661                 return STT_ERROR_PERMISSION_DENIED;
1662         }
1663         if (0 != __stt_check_handle(stt, &client)) {
1664                 return STT_ERROR_INVALID_PARAMETER;
1665         }
1666
1667         SLOG(LOG_INFO, TAG_STTC, "===== STT START");
1668
1669         /* check state */
1670         if (client->current_state != STT_STATE_READY) {
1671                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1672                 return STT_ERROR_INVALID_STATE;
1673         }
1674
1675         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1676                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state); //LCOV_EXCL_LINE
1677                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1678         }
1679
1680         int ret = -1;
1681         char appid[1024] = {0, };
1682         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
1683
1684         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1685                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID"); //LCOV_EXCL_LINE
1686         } else {
1687                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
1688         }
1689
1690         char* temp = NULL;
1691         if (NULL == language) {
1692                 temp = strdup("default");
1693         } else {
1694                 temp = strdup(language);
1695         }
1696
1697         if (NULL == temp) {
1698                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1699                 return STT_ERROR_OUT_OF_MEMORY;
1700         }
1701
1702         if (true == client->credential_needed && NULL == client->credential) {
1703                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id); //LCOV_EXCL_LINE
1704                 free(temp);
1705                 temp = NULL;
1706                 return STT_ERROR_PERMISSION_DENIED;
1707         }
1708
1709         client->internal_state = STT_INTERNAL_STATE_STARTING;
1710         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1711         if (0 != ret) {
1712                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1713                 client->internal_state = STT_INTERNAL_STATE_NONE;
1714         } else {
1715                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
1716         }
1717
1718         free(temp);
1719         temp = NULL;
1720
1721         SLOG(LOG_INFO, TAG_STTC, "=====");
1722         SLOG(LOG_DEBUG, TAG_STTC, " ");
1723
1724         return ret;
1725 }
1726
1727 int stt_stop(stt_h stt)
1728 {
1729         stt_client_s* client = NULL;
1730         if (0 != __stt_get_feature_enabled()) {
1731                 return STT_ERROR_NOT_SUPPORTED;
1732         }
1733         if (0 != __stt_check_privilege()) {
1734                 return STT_ERROR_PERMISSION_DENIED;
1735         }
1736         if (0 != __stt_check_handle(stt, &client)) {
1737                 return STT_ERROR_INVALID_PARAMETER;
1738         }
1739
1740         SLOG(LOG_INFO, TAG_STTC, "===== STT STOP");
1741
1742         /* check state */
1743         if (client->current_state != STT_STATE_RECORDING) {
1744                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state); //LCOV_EXCL_LINE
1745                 return STT_ERROR_INVALID_STATE;
1746         }
1747
1748         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1749                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1750                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1751         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1752                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1753                 return STT_ERROR_IN_PROGRESS_TO_READY;
1754         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1755                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1756                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1757         }
1758
1759         client->internal_state = STT_INTERNAL_STATE_STOPPING;
1760         int ret = stt_dbus_request_stop(client->uid);
1761         if (0 != ret) {
1762                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1763                 client->internal_state = STT_INTERNAL_STATE_NONE;
1764         } else {
1765                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1766         }
1767
1768         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1769         SLOG(LOG_DEBUG, TAG_STTC, " ");
1770
1771         return ret;
1772 }
1773
1774
1775 int stt_cancel(stt_h stt)
1776 {
1777         stt_client_s* client = NULL;
1778         if (0 != __stt_get_feature_enabled()) {
1779                 return STT_ERROR_NOT_SUPPORTED;
1780         }
1781         if (0 != __stt_check_privilege()) {
1782                 return STT_ERROR_PERMISSION_DENIED;
1783         }
1784         if (0 != __stt_check_handle(stt, &client)) {
1785                 return STT_ERROR_INVALID_PARAMETER;
1786         }
1787
1788         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL");
1789
1790         /* check state */
1791         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1792                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state); //LCOV_EXCL_LINE
1793                 return STT_ERROR_INVALID_STATE;
1794         }
1795
1796         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1797                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1798                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1799         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1800                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1801                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1802         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1803                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1804                 return STT_ERROR_IN_PROGRESS_TO_READY;
1805         }
1806
1807         client->internal_state = STT_INTERNAL_STATE_CANCELING;
1808         int ret = stt_dbus_request_cancel(client->uid);
1809         if (0 != ret) {
1810                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1811                 client->internal_state = STT_INTERNAL_STATE_NONE;
1812         } else {
1813                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1814         }
1815
1816         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1817         SLOG(LOG_DEBUG, TAG_STTC, " ");
1818
1819         return ret;
1820 }
1821
1822 int __stt_cb_set_volume(int uid, float volume)
1823 {
1824         stt_client_s* client = NULL;
1825
1826         client = stt_client_get_by_uid(uid);
1827         if (NULL == client) {
1828                 //LCOV_EXCL_START
1829                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1830                 return STT_ERROR_INVALID_PARAMETER;
1831                 //LCOV_EXCL_STOP
1832         }
1833
1834         if (STT_STATE_RECORDING != client->current_state) {
1835                 //LCOV_EXCL_START
1836                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1837                 return STT_ERROR_INVALID_STATE;
1838                 //LCOV_EXCL_STOP
1839         }
1840
1841         g_volume_db = volume;
1842         SLOG(LOG_INFO, TAG_STTC, "Set volume (%f)", g_volume_db);
1843
1844         return 0;
1845 }
1846
1847 int stt_get_recording_volume(stt_h stt, float* volume)
1848 {
1849         stt_client_s* client = NULL;
1850         if (0 != __stt_get_feature_enabled()) {
1851                 return STT_ERROR_NOT_SUPPORTED;
1852         }
1853         if (0 != __stt_check_privilege()) {
1854                 return STT_ERROR_PERMISSION_DENIED;
1855         }
1856         if (0 != __stt_check_handle(stt, &client)) {
1857                 return STT_ERROR_INVALID_PARAMETER;
1858         }
1859
1860         if (NULL == volume) {
1861                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1862                 return STT_ERROR_INVALID_PARAMETER;
1863         }
1864
1865         if (STT_STATE_RECORDING != client->current_state) {
1866                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state); //LCOV_EXCL_LINE
1867                 return STT_ERROR_INVALID_STATE;
1868         }
1869
1870         *volume = g_volume_db;
1871
1872         SLOG(LOG_INFO, TAG_STTC, "Get recording volume (%f)", *volume);
1873
1874         return STT_ERROR_NONE;
1875 }
1876
1877 //LCOV_EXCL_START
1878 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1879 {
1880         stt_client_s* client = (stt_client_s*)user_data;
1881
1882         /* check handle */
1883         if (NULL == client) {
1884                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1885                 return EINA_FALSE;
1886         }
1887
1888         if (NULL != client->result_time_cb) {
1889                 SLOG(LOG_INFO, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1890                         index, event, text, start_time, end_time);
1891                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1892                         text, start_time, end_time, client->result_time_user_data);
1893         } else {
1894                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1895                 return false;
1896         }
1897
1898         return true;
1899 }
1900 //LCOV_EXCL_STOP
1901
1902 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1903 {
1904         stt_client_s* client = NULL;
1905         if (0 != __stt_get_feature_enabled()) {
1906                 return STT_ERROR_NOT_SUPPORTED;
1907         }
1908         if (0 != __stt_check_privilege()) {
1909                 return STT_ERROR_PERMISSION_DENIED;
1910         }
1911         if (0 != __stt_check_handle(stt, &client)) {
1912                 return STT_ERROR_INVALID_PARAMETER;
1913         }
1914
1915         SLOG(LOG_INFO, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1916
1917         if (NULL == callback) {
1918                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1919                 return STT_ERROR_INVALID_PARAMETER;
1920         }
1921
1922         client->result_time_cb = callback;
1923         client->result_time_user_data = user_data;
1924
1925         int ret = -1;
1926         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1927         ret = __stt_convert_config_error_code(ret);
1928         if (0 != ret) {
1929                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1930         }
1931
1932         client->result_time_cb = NULL;
1933         client->result_time_user_data = NULL;
1934
1935         SLOG(LOG_INFO, TAG_STTC, "=====");
1936         SLOG(LOG_DEBUG, TAG_STTC, " ");
1937
1938         return ret;
1939 }
1940
1941 static void __stt_notify_error(void *data)
1942 {
1943         stt_client_s* client = (stt_client_s*)data;
1944
1945         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1946
1947         /* check handle */
1948         if (NULL == client) {
1949                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
1950                 return;
1951         }
1952
1953         if (NULL == stt_client_get_by_uid(client->uid))
1954                 return;
1955
1956         if (NULL != client->error_cb) {
1957                 stt_client_use_callback(client);
1958                 g_err_callback_status = true;
1959                 client->error_cb(client->stt, client->reason, client->error_user_data);
1960                 g_err_callback_status = false;
1961                 stt_client_not_use_callback(client);
1962                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1963         } else {
1964                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); //LCOV_EXCL_LINE
1965         }
1966
1967         return;
1968 }
1969
1970 int __stt_cb_error(int uid, int reason, char* err_msg)
1971 {
1972         //LCOV_EXCL_START
1973         if (-1 == uid) {
1974                 GList* client_list = NULL;
1975                 client_list = stt_client_get_client_list();
1976
1977                 GList *iter = NULL;
1978                 stt_client_s *data = NULL;
1979
1980                 if (g_list_length(client_list) > 0) {
1981                         /* Get a first item */
1982                         iter = g_list_first(client_list);
1983
1984                         while (NULL != iter) {
1985                                 data = iter->data;
1986
1987                                 data->reason = reason;
1988                                 data->internal_state = STT_INTERNAL_STATE_NONE;
1989                                 if (NULL != data->err_msg) {
1990                                         free(data->err_msg);
1991                                         data->err_msg = NULL;
1992                                 }
1993                                 if (NULL != err_msg)
1994                                         data->err_msg = strdup(err_msg);
1995
1996                                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
1997
1998                                 if (NULL != data->error_cb) {
1999                                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, data);
2000                                 } else {
2001                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2002                                 }
2003
2004                                 if (STT_ERROR_SERVICE_RESET == reason) {
2005                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset");
2006
2007                                         data->current_state = STT_STATE_CREATED;
2008                                         if (0 != stt_prepare(data->stt)) {
2009                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare");
2010                                         }
2011                                 }
2012
2013                                 /* Next item */
2014                                 iter = g_list_next(iter);
2015                         }
2016                 }
2017                 //LCOV_EXCL_STOP
2018         } else {
2019                 stt_client_s* client = stt_client_get_by_uid(uid);
2020                 if (NULL == client) {
2021                         SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2022                         return -1;
2023                 }
2024
2025                 client->reason = reason;
2026                 client->internal_state = STT_INTERNAL_STATE_NONE;
2027                 if (NULL != client->err_msg) {
2028                         free(client->err_msg);
2029                         client->err_msg = NULL;
2030                 }
2031                 if (NULL != err_msg)
2032                         client->err_msg = strdup(err_msg);
2033
2034                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
2035
2036                 if (NULL != client->error_cb) {
2037                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, client);
2038                 } else {
2039                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2040                 }
2041
2042                 if (STT_ERROR_SERVICE_RESET == reason) {
2043                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); //LCOV_EXCL_LINE
2044
2045                         client->current_state = STT_STATE_CREATED;
2046                         if (0 != stt_prepare(client->stt)) {
2047                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); //LCOV_EXCL_LINE
2048                         }
2049                 }
2050         }
2051
2052         return 0;
2053 }
2054
2055 static void __stt_notify_state_changed(void *data)
2056 {
2057         stt_client_s* client = (stt_client_s*)data;
2058
2059         /* check handle */
2060         if (NULL == client) {
2061                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2062                 return;
2063         }
2064
2065         if (NULL == stt_client_get_by_uid(client->uid)) {
2066                 return;
2067         }
2068
2069         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
2070                 client->internal_state = STT_INTERNAL_STATE_NONE;
2071                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2072         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
2073                 client->internal_state = STT_INTERNAL_STATE_NONE;
2074                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2075         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
2076                 client->internal_state = STT_INTERNAL_STATE_NONE;
2077                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2078         }
2079
2080         if (NULL != client->state_changed_cb) {
2081                 stt_client_use_callback(client);
2082                 client->state_changed_cb(client->stt, client->before_state,
2083                         client->current_state, client->state_changed_user_data);
2084                 stt_client_not_use_callback(client);
2085                 SLOG(LOG_INFO, TAG_STTC, "State changed callback is called, State(%d)", client->current_state);
2086         } else {
2087                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null, State(%d)", client->current_state); //LCOV_EXCL_LINE
2088         }
2089
2090         return;
2091 }
2092
2093 static Eina_Bool __stt_notify_result(void *data)
2094 {
2095         stt_client_s* client = (stt_client_s*)data;
2096
2097         /* check handle */
2098         if (NULL == client) {
2099                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2100                 return EINA_FALSE;
2101         }
2102
2103         if (NULL == stt_client_get_by_uid(client->uid)) {
2104                 return EINA_FALSE;
2105         }
2106
2107         if (NULL != client->recognition_result_cb) {
2108                 stt_client_use_callback(client);
2109                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
2110                         client->msg, client->recognition_result_user_data);
2111                 stt_client_not_use_callback(client);
2112                 SLOG(LOG_INFO, TAG_STTC, "client recognition result callback called");
2113         } else {
2114                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
2115         }
2116
2117         if (NULL != client->msg) {
2118                 free(client->msg);
2119                 client->msg = NULL;
2120         }
2121
2122         if (NULL != client->data_list) {
2123                 char **temp = NULL;
2124                 temp = client->data_list;
2125
2126                 int i = 0;
2127                 for (i = 0; i < client->data_count; i++) {
2128                         if (NULL != temp[i]) {
2129                                 free(temp[i]);
2130                                 temp[i] = NULL;
2131                         } else {
2132                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2133                         }
2134                 }
2135                 free(client->data_list);
2136                 client->data_list = NULL;
2137         }
2138
2139         client->data_count = 0;
2140
2141         stt_config_mgr_remove_time_info_file();
2142
2143         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
2144                 client->before_state = client->current_state;
2145                 client->current_state = STT_STATE_READY;
2146
2147                 if (NULL != client->state_changed_cb) {
2148                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2149                 } else {
2150                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null"); //LCOV_EXCL_LINE
2151                 }
2152         }
2153
2154         return EINA_FALSE;
2155 }
2156
2157 int __stt_cb_result(int uid, int event, char** data, int data_count, const char* msg)
2158 {
2159         stt_client_s* client = NULL;
2160
2161         client = stt_client_get_by_uid(uid);
2162         if (NULL == client) {
2163                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid"); //LCOV_EXCL_LINE
2164                 return STT_ERROR_INVALID_PARAMETER;
2165         }
2166
2167         if (NULL != msg)
2168                 SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result Message = %s", msg);
2169
2170         int i = 0;
2171         for (i = 0; i < data_count; i++) {
2172                 if (NULL != data[i])
2173                         SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
2174         }
2175
2176         if (NULL != client->recognition_result_cb) {
2177                 client->event = event;
2178                 if (NULL != msg) {
2179                         client->msg = strdup(msg);
2180                 }
2181
2182                 client->data_count = data_count;
2183
2184                 if (data_count > 0) {
2185                         char **temp = NULL;
2186                         temp = (char**)calloc(data_count, sizeof(char*));
2187                         if (NULL == temp) {
2188                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
2189                                 return STT_ERROR_OUT_OF_MEMORY;
2190                         }
2191
2192                         for (i = 0; i < data_count; i++) {
2193                                 if (NULL != data[i])
2194                                         temp[i] = strdup(data[i]);
2195                                 else
2196                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2197                         }
2198
2199                         client->data_list = temp;
2200                 }
2201         } else {
2202                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
2203         }
2204
2205         __stt_notify_result(client);
2206
2207         return STT_ERROR_NONE;
2208 }
2209
2210 int __stt_cb_set_state(int uid, int state)
2211 {
2212         stt_client_s* client = stt_client_get_by_uid(uid);
2213         if (NULL == client) {
2214                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2215                 return -1;
2216         }
2217
2218         stt_state_e state_from_daemon = (stt_state_e)state;
2219
2220         if (client->current_state == state_from_daemon) {
2221                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
2222                 return 0;
2223         }
2224
2225         client->before_state = client->current_state;
2226         client->current_state = state_from_daemon;
2227
2228         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2229         return 0;
2230 }
2231
2232 static void __stt_notify_speech_status(void *data)
2233 {
2234         stt_client_s* client = (stt_client_s*)data;
2235
2236         /* check handle */
2237         if (NULL == client) {
2238                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify speech status : A handle is not valid"); //LCOV_EXCL_LINE
2239                 return;
2240         }
2241
2242         if (NULL == stt_client_get_by_uid(client->uid)) {
2243                 return;
2244         }
2245
2246         if (NULL != client->speech_status_cb) {
2247                 stt_client_use_callback(client);
2248                 client->speech_status_cb(client->stt, client->speech_status, client->speech_status_user_data);
2249                 stt_client_not_use_callback(client);
2250                 SLOG(LOG_INFO, TAG_STTC, "Speech status callback is called"); //LCOV_EXCL_LINE
2251         } else {
2252                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Speech status callback is null"); //LCOV_EXCL_LINE
2253         }
2254
2255         return;
2256 }
2257
2258 int __stt_cb_speech_status(int uid, int status)
2259 {
2260         stt_client_s* client = stt_client_get_by_uid(uid);
2261         if (NULL == client) {
2262                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2263                 return -1;
2264         }
2265
2266         client->speech_status = status;
2267
2268         ecore_main_loop_thread_safe_call_async(__stt_notify_speech_status, client);
2269         return 0;
2270 }
2271
2272 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
2273 {
2274         stt_client_s* client = NULL;
2275         if (0 != __stt_get_feature_enabled()) {
2276                 return STT_ERROR_NOT_SUPPORTED;
2277         }
2278         if (0 != __stt_check_privilege()) {
2279                 return STT_ERROR_PERMISSION_DENIED;
2280         }
2281         if (0 != __stt_check_handle(stt, &client)) {
2282                 return STT_ERROR_INVALID_PARAMETER;
2283         }
2284
2285         if (callback == NULL)
2286                 return STT_ERROR_INVALID_PARAMETER;
2287
2288         if (STT_STATE_CREATED != client->current_state) {
2289                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2290                 return STT_ERROR_INVALID_STATE;
2291         }
2292
2293         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set recognition result cb");
2294
2295         client->recognition_result_cb = callback;
2296         client->recognition_result_user_data = user_data;
2297
2298         return 0;
2299 }
2300
2301 int stt_unset_recognition_result_cb(stt_h stt)
2302 {
2303         stt_client_s* client = NULL;
2304         if (0 != __stt_get_feature_enabled()) {
2305                 return STT_ERROR_NOT_SUPPORTED;
2306         }
2307         if (0 != __stt_check_privilege()) {
2308                 return STT_ERROR_PERMISSION_DENIED;
2309         }
2310         if (0 != __stt_check_handle(stt, &client)) {
2311                 return STT_ERROR_INVALID_PARAMETER;
2312         }
2313
2314         if (STT_STATE_CREATED != client->current_state) {
2315                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2316                 return STT_ERROR_INVALID_STATE;
2317         }
2318
2319         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset recognition result cb");
2320
2321         client->recognition_result_cb = NULL;
2322         client->recognition_result_user_data = NULL;
2323
2324         return 0;
2325 }
2326
2327 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
2328 {
2329         stt_client_s* client = NULL;
2330         if (0 != __stt_get_feature_enabled()) {
2331                 return STT_ERROR_NOT_SUPPORTED;
2332         }
2333         if (0 != __stt_check_privilege()) {
2334                 return STT_ERROR_PERMISSION_DENIED;
2335         }
2336         if (0 != __stt_check_handle(stt, &client)) {
2337                 return STT_ERROR_INVALID_PARAMETER;
2338         }
2339
2340         if (NULL == callback)
2341                 return STT_ERROR_INVALID_PARAMETER;
2342
2343         if (STT_STATE_CREATED != client->current_state) {
2344                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2345                 return STT_ERROR_INVALID_STATE;
2346         }
2347
2348         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set state changed cb");
2349
2350         client->state_changed_cb = callback;
2351         client->state_changed_user_data = user_data;
2352
2353         return 0;
2354 }
2355
2356 int stt_unset_state_changed_cb(stt_h stt)
2357 {
2358         stt_client_s* client = NULL;
2359         if (0 != __stt_get_feature_enabled()) {
2360                 return STT_ERROR_NOT_SUPPORTED;
2361         }
2362         if (0 != __stt_check_privilege()) {
2363                 return STT_ERROR_PERMISSION_DENIED;
2364         }
2365         if (0 != __stt_check_handle(stt, &client)) {
2366                 return STT_ERROR_INVALID_PARAMETER;
2367         }
2368
2369         if (STT_STATE_CREATED != client->current_state) {
2370                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2371                 return STT_ERROR_INVALID_STATE;
2372         }
2373
2374         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset state changed cb");
2375
2376         client->state_changed_cb = NULL;
2377         client->state_changed_user_data = NULL;
2378
2379         return 0;
2380 }
2381
2382 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
2383 {
2384         stt_client_s* client = NULL;
2385         if (0 != __stt_get_feature_enabled()) {
2386                 return STT_ERROR_NOT_SUPPORTED;
2387         }
2388         if (0 != __stt_check_privilege()) {
2389                 return STT_ERROR_PERMISSION_DENIED;
2390         }
2391         if (0 != __stt_check_handle(stt, &client)) {
2392                 return STT_ERROR_INVALID_PARAMETER;
2393         }
2394
2395         if (NULL == callback)
2396                 return STT_ERROR_INVALID_PARAMETER;
2397
2398         if (STT_STATE_CREATED != client->current_state) {
2399                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2400                 return STT_ERROR_INVALID_STATE;
2401         }
2402
2403         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set error cb");
2404
2405         client->error_cb = callback;
2406         client->error_user_data = user_data;
2407
2408         return 0;
2409 }
2410
2411 int stt_unset_error_cb(stt_h stt)
2412 {
2413         stt_client_s* client = NULL;
2414         if (0 != __stt_get_feature_enabled()) {
2415                 return STT_ERROR_NOT_SUPPORTED;
2416         }
2417         if (0 != __stt_check_privilege()) {
2418                 return STT_ERROR_PERMISSION_DENIED;
2419         }
2420         if (0 != __stt_check_handle(stt, &client)) {
2421                 return STT_ERROR_INVALID_PARAMETER;
2422         }
2423
2424         if (STT_STATE_CREATED != client->current_state) {
2425                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2426                 return STT_ERROR_INVALID_STATE;
2427         }
2428
2429         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset error cb");
2430
2431         client->error_cb = NULL;
2432         client->error_user_data = NULL;
2433
2434         return 0;
2435 }
2436
2437 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2438 {
2439         stt_client_s* client = NULL;
2440         if (0 != __stt_get_feature_enabled()) {
2441                 return STT_ERROR_NOT_SUPPORTED;
2442         }
2443         if (0 != __stt_check_privilege()) {
2444                 return STT_ERROR_PERMISSION_DENIED;
2445         }
2446         if (0 != __stt_check_handle(stt, &client)) {
2447                 return STT_ERROR_INVALID_PARAMETER;
2448         }
2449
2450         if (NULL == callback)
2451                 return STT_ERROR_INVALID_PARAMETER;
2452
2453         if (STT_STATE_CREATED != client->current_state) {
2454                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2455                 return STT_ERROR_INVALID_STATE;
2456         }
2457
2458         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set default language changed cb");
2459
2460         client->default_lang_changed_cb = callback;
2461         client->default_lang_changed_user_data = user_data;
2462
2463         return 0;
2464 }
2465
2466 int stt_unset_default_language_changed_cb(stt_h stt)
2467 {
2468         stt_client_s* client = NULL;
2469         if (0 != __stt_get_feature_enabled()) {
2470                 return STT_ERROR_NOT_SUPPORTED;
2471         }
2472         if (0 != __stt_check_privilege()) {
2473                 return STT_ERROR_PERMISSION_DENIED;
2474         }
2475         if (0 != __stt_check_handle(stt, &client)) {
2476                 return STT_ERROR_INVALID_PARAMETER;
2477         }
2478
2479         if (STT_STATE_CREATED != client->current_state) {
2480                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2481                 return STT_ERROR_INVALID_STATE;
2482         }
2483
2484         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset default language changed cb");
2485
2486         client->default_lang_changed_cb = NULL;
2487         client->default_lang_changed_user_data = NULL;
2488
2489         return 0;
2490 }
2491
2492 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2493 {
2494         stt_client_s* client = NULL;
2495         if (0 != __stt_get_feature_enabled()) {
2496                 return STT_ERROR_NOT_SUPPORTED;
2497         }
2498         if (0 != __stt_check_privilege()) {
2499                 return STT_ERROR_PERMISSION_DENIED;
2500         }
2501         if (0 != __stt_check_handle(stt, &client)) {
2502                 return STT_ERROR_INVALID_PARAMETER;
2503         }
2504
2505         if (NULL == callback)
2506                 return STT_ERROR_INVALID_PARAMETER;
2507
2508         if (STT_STATE_CREATED != client->current_state) {
2509                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2510                 return STT_ERROR_INVALID_STATE;
2511         }
2512
2513         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set engine changed cb");
2514
2515         client->engine_changed_cb = callback;
2516         client->engine_changed_user_data = user_data;
2517
2518         return 0;
2519 }
2520
2521 int stt_unset_engine_changed_cb(stt_h stt)
2522 {
2523         stt_client_s* client = NULL;
2524         if (0 != __stt_get_feature_enabled()) {
2525                 return STT_ERROR_NOT_SUPPORTED;
2526         }
2527         if (0 != __stt_check_privilege()) {
2528                 return STT_ERROR_PERMISSION_DENIED;
2529         }
2530         if (0 != __stt_check_handle(stt, &client)) {
2531                 return STT_ERROR_INVALID_PARAMETER;
2532         }
2533
2534         if (STT_STATE_CREATED != client->current_state) {
2535                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2536                 return STT_ERROR_INVALID_STATE;
2537         }
2538
2539         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset engine changed cb");
2540
2541         client->engine_changed_cb = NULL;
2542         client->engine_changed_user_data = NULL;
2543
2544         return 0;
2545 }
2546
2547 //LCOV_EXCL_START
2548 int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data)
2549 {
2550         stt_client_s* client = NULL;
2551         if (0 != __stt_get_feature_enabled()) {
2552                 return STT_ERROR_NOT_SUPPORTED;
2553         }
2554         if (0 != __stt_check_privilege()) {
2555                 return STT_ERROR_PERMISSION_DENIED;
2556         }
2557         if (0 != __stt_check_handle(stt, &client)) {
2558                 return STT_ERROR_INVALID_PARAMETER;
2559         }
2560
2561         if (NULL == callback)
2562                 return STT_ERROR_INVALID_PARAMETER;
2563
2564         if (STT_STATE_CREATED != client->current_state) {
2565                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2566                 return STT_ERROR_INVALID_STATE;
2567         }
2568
2569         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set speech status cb");
2570
2571         client->speech_status_cb = callback;
2572         client->speech_status_user_data = user_data;
2573
2574         return 0;
2575 }
2576
2577 int stt_unset_speech_status_cb(stt_h stt)
2578 {
2579         stt_client_s* client = NULL;
2580         if (0 != __stt_get_feature_enabled()) {
2581                 return STT_ERROR_NOT_SUPPORTED;
2582         }
2583         if (0 != __stt_check_privilege()) {
2584                 return STT_ERROR_PERMISSION_DENIED;
2585         }
2586         if (0 != __stt_check_handle(stt, &client)) {
2587                 return STT_ERROR_INVALID_PARAMETER;
2588         }
2589
2590         if (STT_STATE_CREATED != client->current_state) {
2591                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2592                 return STT_ERROR_INVALID_STATE;
2593         }
2594
2595         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset speech status cb");
2596
2597         client->speech_status_cb = NULL;
2598         client->speech_status_user_data = NULL;
2599
2600         return 0;
2601 }
2602
2603 int stt_start_file(stt_h stt, const char* language, const char* type, const char* filepath, stt_audio_type_e audio_type, int sample_rate)
2604 {
2605         stt_client_s* client = NULL;
2606         if (0 != __stt_get_feature_enabled()) {
2607                 return STT_ERROR_NOT_SUPPORTED;
2608         }
2609         if (0 != __stt_check_privilege()) {
2610                 return STT_ERROR_PERMISSION_DENIED;
2611         }
2612         if (0 != __stt_check_handle(stt, &client)) {
2613                 return STT_ERROR_INVALID_PARAMETER;
2614         }
2615         if (NULL == filepath) {
2616                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
2617                 return STT_ERROR_INVALID_PARAMETER;
2618         }
2619
2620         SLOG(LOG_INFO, TAG_STTC, "===== STT START FILE");
2621
2622         /* check state */
2623         if (client->current_state != STT_STATE_READY) {
2624                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
2625                 return STT_ERROR_INVALID_STATE;
2626         }
2627
2628         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
2629                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
2630                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2631         }
2632
2633         int ret = -1;
2634         char appid[1024] = {0, };
2635         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
2636
2637         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
2638                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
2639         } else {
2640                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Current app id is %s", appid);
2641         }
2642
2643         char* temp = NULL;
2644         if (NULL == language) {
2645                 temp = strdup("default");
2646         } else {
2647                 temp = strdup(language);
2648         }
2649
2650         if (NULL == temp) {
2651                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
2652                 return STT_ERROR_OUT_OF_MEMORY;
2653         }
2654
2655         if (true == client->credential_needed && NULL == client->credential) {
2656                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
2657                 free(temp);
2658                 temp = NULL;
2659                 return STT_ERROR_PERMISSION_DENIED;
2660         }
2661
2662         client->internal_state = STT_INTERNAL_STATE_STARTING;
2663         ret = stt_dbus_request_start_file(client->uid, temp, type, client->silence, appid, client->credential, filepath, audio_type, sample_rate);
2664         if (0 != ret) {
2665                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start file : %s", __stt_get_error_code(ret));
2666                 client->internal_state = STT_INTERNAL_STATE_NONE;
2667         } else {
2668                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
2669         }
2670
2671         free(temp);
2672         temp = NULL;
2673
2674         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2675         SLOG(LOG_DEBUG, TAG_STTC, " ");
2676
2677         return ret;
2678 }
2679
2680 int stt_cancel_file(stt_h stt)
2681 {
2682         stt_client_s* client = NULL;
2683         if (0 != __stt_get_feature_enabled()) {
2684                 return STT_ERROR_NOT_SUPPORTED;
2685         }
2686         if (0 != __stt_check_privilege()) {
2687                 return STT_ERROR_PERMISSION_DENIED;
2688         }
2689         if (0 != __stt_check_handle(stt, &client)) {
2690                 return STT_ERROR_INVALID_PARAMETER;
2691         }
2692
2693         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL FILE");
2694
2695         /* check state */
2696         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
2697                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
2698                 return STT_ERROR_INVALID_STATE;
2699         }
2700
2701         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
2702                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
2703                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2704         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
2705                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
2706                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
2707         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
2708                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
2709                 return STT_ERROR_IN_PROGRESS_TO_READY;
2710         }
2711
2712         client->internal_state = STT_INTERNAL_STATE_CANCELING;
2713         int ret = stt_dbus_request_cancel_file(client->uid);
2714         if (0 != ret) {
2715                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel file : %s", __stt_get_error_code(ret));
2716                 client->internal_state = STT_INTERNAL_STATE_NONE;
2717         } else {
2718                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel file is successful but not done");
2719         }
2720
2721         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2722         SLOG(LOG_DEBUG, TAG_STTC, " ");
2723
2724         return ret;
2725 }
2726 //LCOV_EXCL_STOP