Add command list handle check logic
[platform/core/uifw/voice-control.git] / client / vc_mgr.c
index 603e112..4609a1a 100644 (file)
 
 static Ecore_Timer* g_m_connect_timer = NULL;
 
+static Ecore_Timer* g_m_set_volume_timer = NULL;
+
 static vc_h g_vc_m = NULL;
 
 static GSList* g_demandable_client_list = NULL;
 
 static float g_volume_db = 0;
 
+static float g_prev_volume_db = 0;
+
+static float g_cur_volume_db = 0;
+
 static int g_daemon_pid = 0;
 
 static int g_feature_enabled = -1;
 
+static bool g_err_callback_status = false;
+
 static Eina_Bool __vc_mgr_notify_state_changed(void *data);
 static Eina_Bool __vc_mgr_notify_error(void *data);
 static Eina_Bool __vc_mgr_notify_result(void *data);
@@ -177,6 +185,8 @@ static void __vc_mgr_internal_unprepare()
        if (0 != ret) {
                SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request finalize : %s", __vc_mgr_get_error_code(ret));
        }
+
+       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE);
        return;
 }
 
@@ -203,6 +213,7 @@ int vc_mgr_deinitialize()
                if (NULL != g_m_connect_timer) {
                        SLOG(LOG_DEBUG, TAG_VCM, "Connect Timer is deleted");
                        ecore_timer_del(g_m_connect_timer);
+                       g_m_connect_timer = NULL;
                }
 
                vc_config_mgr_unset_lang_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
@@ -623,12 +634,12 @@ int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support)
        }
 
        switch (format) {
-               case VC_CMD_FORMAT_FIXED:               *support = true;                break;
-               case VC_CMD_FORMAT_FIXED_AND_VFIXED:    *support = true;                break;
-               case VC_CMD_FORMAT_VFIXED_AND_FIXED:    *support = true;                break;
-               case VC_CMD_FORMAT_FIXED_AND_NONFIXED:  *support = non_fixed_support;   break;
-               case VC_CMD_FORMAT_NONFIXED_AND_FIXED:  *support = non_fixed_support;   break;
-               default:                                *support = false;               break;
+       case VC_CMD_FORMAT_FIXED:               *support = true;                break;
+       case VC_CMD_FORMAT_FIXED_AND_VFIXED:    *support = true;                break;
+       case VC_CMD_FORMAT_VFIXED_AND_FIXED:    *support = true;                break;
+       case VC_CMD_FORMAT_FIXED_AND_NONFIXED:  *support = non_fixed_support;   break;
+       case VC_CMD_FORMAT_NONFIXED_AND_FIXED:  *support = non_fixed_support;   break;
+       default:                                *support = false;               break;
        }
 
        SLOG(LOG_ERROR, TAG_VCM, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false");
@@ -639,6 +650,118 @@ int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support)
        return VC_ERROR_NONE;
 }
 
+int vc_mgr_enable_command_type(int cmd_type)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Enable Command Type");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret;
+       int count = 0;
+       do {
+               ret = vc_mgr_dbus_request_enable_command_type(g_vc_m->handle, cmd_type);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request enable command type : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request enable command type : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       } while (0 != ret);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_disable_command_type(int cmd_type)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Disable Command Type");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret;
+       int count = 0;
+       do {
+               ret = vc_mgr_dbus_request_disable_command_type(g_vc_m->handle, cmd_type);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request disable command type : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request disable command type : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       } while (0 != ret);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
 int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list)
 {
        SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set Command list");
@@ -669,8 +792,19 @@ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list)
                return VC_ERROR_INVALID_STATE;
        }
 
+       if (NULL == vc_cmd_list) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
        vc_cmd_list_s* list = NULL;
        list = (vc_cmd_list_s*)vc_cmd_list;
+       SLOG(LOG_INFO, TAG_VCM, "[List] (%p) (%p)", list, list->list);
+
+       if (NULL == list->list) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid command list");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
 
        int i;
        int ret;
@@ -1553,6 +1687,14 @@ int vc_mgr_start(bool exclusive_command_option)
                return VC_ERROR_INVALID_STATE;
        }
 
+       /* Check internal state for async */
+       vc_internal_state_e internal_state = -1;
+       vc_mgr_client_get_internal_state(g_vc_m, &internal_state);
+       if (internal_state != VC_INTERNAL_STATE_NONE) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invaid State : Internal state is NOT none : %d", internal_state);
+               return VC_ERROR_IN_PROGRESS_TO_RECORDING;
+       }
+
        vc_mgr_client_set_exclusive_command(g_vc_m, exclusive_command_option);
 
        bool start_by_client = false;
@@ -1588,9 +1730,14 @@ int vc_mgr_start(bool exclusive_command_option)
                        }
                } else {
                        SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] start recognition");
+                       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_STARTING);
                }
        }
 
+       g_volume_db = 0;
+       g_prev_volume_db = 0;
+       g_cur_volume_db = 0;
+
        SLOG(LOG_DEBUG, TAG_VCM, "=====");
        SLOG(LOG_DEBUG, TAG_VCM, " ");
 
@@ -1627,6 +1774,20 @@ int vc_mgr_stop()
                return VC_ERROR_INVALID_STATE;
        }
 
+       /* Check internal state for async */
+       vc_internal_state_e internal_state = -1;
+       vc_mgr_client_get_internal_state(g_vc_m, &internal_state);
+       if (VC_INTERNAL_STATE_STARTING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STARTING");
+               return VC_ERROR_IN_PROGRESS_TO_RECORDING;
+       } else if (VC_INTERNAL_STATE_STOPPING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STOPPING");
+               return VC_ERROR_IN_PROGRESS_TO_PROCESSING;
+       } else if (VC_INTERNAL_STATE_CANCELING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is CANCELING");
+               return VC_ERROR_IN_PROGRESS_TO_READY;
+       }
+
        int ret = -1;
        int count = 0;
        /* do request */
@@ -1647,6 +1808,7 @@ int vc_mgr_stop()
                        }
                } else {
                        SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Stop recognition");
+                       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_STOPPING);
                }
        }
 
@@ -1686,6 +1848,19 @@ int vc_mgr_cancel()
                return VC_ERROR_INVALID_STATE;
        }
 
+       vc_internal_state_e internal_state = -1;
+       vc_mgr_client_get_internal_state(g_vc_m, &internal_state);
+       if (VC_INTERNAL_STATE_STARTING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STARTING");
+               return VC_ERROR_IN_PROGRESS_TO_RECORDING;
+       } else if (VC_INTERNAL_STATE_STOPPING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STOPPING");
+               return VC_ERROR_IN_PROGRESS_TO_PROCESSING;
+       } else if (VC_INTERNAL_STATE_CANCELING == internal_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is CANCELING");
+               return VC_ERROR_IN_PROGRESS_TO_READY;
+       }
+
        int ret = -1;
        int count = 0;
        while (0 != ret) {
@@ -1705,6 +1880,7 @@ int vc_mgr_cancel()
                        }
                } else {
                        SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Cancel recognition");
+                       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_CANCELING);
                }
        }
 
@@ -1716,10 +1892,36 @@ int vc_mgr_cancel()
        return ret;
 }
 
+static int g_cnt = 0;
+static Eina_Bool __vc_mgr_set_volume(void* data)
+{
+       g_cnt++;
+       g_volume_db = g_prev_volume_db + (g_cur_volume_db - g_prev_volume_db) / 5 * g_cnt;
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Set volume (%f)(%f)", g_volume_db, g_cur_volume_db);
+
+       if (0 == g_cnt % 5) {
+               return EINA_FALSE;
+       }
+       return EINA_TRUE;
+}
+
 int __vc_mgr_cb_set_volume(float volume)
 {
-       g_volume_db = volume;
-       SLOG(LOG_DEBUG, TAG_VCM, "Set volume (%f)", g_volume_db);
+       g_prev_volume_db = g_volume_db;
+       g_cur_volume_db = volume;
+
+       g_volume_db = g_prev_volume_db + (g_cur_volume_db - g_prev_volume_db) / 5;
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Set volume (%f)(%f)", g_volume_db, g_cur_volume_db);
+
+       if (NULL != g_m_set_volume_timer) {
+               SLOG(LOG_DEBUG, TAG_VCM, "Connect Timer is deleted");
+               ecore_timer_del(g_m_set_volume_timer);
+       }
+
+       g_cnt = 1;
+       g_m_set_volume_timer = ecore_timer_add(0.05, __vc_mgr_set_volume, NULL);
 
        return 0;
 }
@@ -1880,7 +2082,7 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type)
 
        vc_info_parser_get_result(&temp_text, &event, &temp_message, -1, vc_cmd_list, vc_mgr_client_get_exclusive_command(g_vc_m));
 
-       SLOG(LOG_DEBUG, TAG_VCM, "Result info : result type(%d) result text(%s) event(%d) result_message(%s)", 
+       SLOG(LOG_INFO, TAG_VCM, "Result info : result type(%d) result text(%s) event(%d) result_message(%s)", 
                result_type, temp_text, event, temp_message);
 
        vc_cmd_print_list(vc_cmd_list);
@@ -1972,14 +2174,14 @@ static Eina_Bool __vc_mgr_notify_result(void *data)
 
        vc_info_parser_get_result(&temp_text, &event, NULL, getpid(), vc_cmd_list, false);
 
-       SLOG(LOG_DEBUG, TAG_VCM, "Result : result text(%s) event(%d)", temp_text, event);
+       SLOG(LOG_INFO, TAG_VCM, "Result : result text(%s) event(%d)", temp_text, event);
 
        vc_cmd_print_list(vc_cmd_list);
 
        vc_mgr_client_use_callback(g_vc_m);
        callback(event, vc_cmd_list, temp_text, user_data);
        vc_mgr_client_not_use_callback(g_vc_m);
-       SLOG(LOG_DEBUG, TAG_VCM, "Result callback called");
+       SLOG(LOG_INFO, TAG_VCM, "Result callback called");
 
        vc_cmd_list_destroy(vc_cmd_list, true);
 
@@ -2176,6 +2378,32 @@ int vc_mgr_unset_pre_result_cb()
        return 0;
 }
 
+int vc_mgr_get_error_message(char** err_msg)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get error message");
+
+       if (NULL == err_msg) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] invalid parameter");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (false == g_err_callback_status) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not in error callback");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       int ret;
+       ret = vc_mgr_client_get_error_message(g_vc_m, err_msg);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get error message");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
 static Eina_Bool __vc_mgr_notify_error(void *data)
 {
        vc_h vc_m = (vc_h)data;
@@ -2189,7 +2417,9 @@ static Eina_Bool __vc_mgr_notify_error(void *data)
 
        if (NULL != callback) {
                vc_mgr_client_use_callback(vc_m);
+               g_err_callback_status = true;
                callback(reason, user_data);
+               g_err_callback_status = false;
                vc_mgr_client_not_use_callback(vc_m);
                SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called");
        } else {
@@ -2213,6 +2443,8 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg)
                return -1;
        }
 
+       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE);
+
        if (VC_ERROR_SERVICE_RESET == reason) {
                SLOG(LOG_ERROR, TAG_VCM, "[ERROR] VC daemon reset");
 
@@ -2227,6 +2459,7 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg)
        SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg);
 
        vc_mgr_client_set_error(g_vc_m, reason);
+       vc_mgr_client_set_error_message(g_vc_m, msg);
        __vc_mgr_notify_error(g_vc_m);
 
        return 0;
@@ -2313,6 +2546,15 @@ int __vc_mgr_cb_service_state(int state)
        SLOG(LOG_DEBUG, TAG_VCM, "Service State changed : Before(%d) Current(%d)",
                before_state, current_state);
 
+       vc_internal_state_e internal_state = -1;
+       vc_mgr_client_get_internal_state(g_vc_m, &internal_state);
+       if ((VC_INTERNAL_STATE_STARTING == internal_state && VC_SERVICE_STATE_RECORDING == current_state) ||
+               (VC_INTERNAL_STATE_STOPPING == internal_state && VC_SERVICE_STATE_PROCESSING == current_state) ||
+               (VC_INTERNAL_STATE_CANCELING == internal_state && VC_SERVICE_STATE_READY == current_state)) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "Internal state is changed to NONE");
+                       vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE);
+       }
+
        /* Save service state */
        vc_mgr_client_set_service_state(g_vc_m, current_state);