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