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