Add internal method to get speech status info 78/99878/3
authorKwangyoun Kim <ky85.kim@samsung.com>
Thu, 24 Nov 2016 10:18:54 +0000 (19:18 +0900)
committerKwangyoun Kim <ky85.kim@samsung.com>
Thu, 24 Nov 2016 11:00:15 +0000 (20:00 +0900)
Change-Id: Ie07311ba2af1c29ab1cfe8f2be36d69869d8fa97
Signed-off-by: Kwangyoun Kim <ky85.kim@samsung.com>
client/stt.c
client/stt_client.c
client/stt_client.h
client/stt_dbus.c
common/stt_defs.h
include/CMakeLists.txt
include/stt_internal.h [new file with mode: 0644]
packaging/stt.spec
server/sttd_dbus.c
server/sttd_dbus.h
server/sttd_server.c

index faf821f..4595139 100644 (file)
@@ -30,6 +30,7 @@
 #include "stt_client.h"
 #include "stt_dbus.h"
 #include "stt_config_mgr.h"
+#include "stt_internal.h"
 #include "stt_main.h"
 
 
@@ -1936,6 +1937,46 @@ int __stt_cb_set_state(int uid, int state)
        return 0;
 }
 
+static void __stt_notify_speech_status(void *data)
+{
+       stt_client_s* client = (stt_client_s*)data;
+
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify speech status : A handle is not valid");
+               return;
+       }
+
+       if (NULL == stt_client_get_by_uid(client->uid)) {
+               return;
+       }
+
+       if (NULL != client->speech_status_cb) {
+               stt_client_use_callback(client);
+               client->speech_status_cb(client->stt, client->speech_status, client->speech_status_user_data);
+               stt_client_not_use_callback(client);
+               SLOG(LOG_DEBUG, TAG_STTC, "Speech status callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_STTC, "[WARNING] Speech status callback is null");
+       }
+
+       return;
+}
+
+int __stt_cb_speech_status(int uid, int status)
+{
+       stt_client_s* client = stt_client_get_by_uid(uid);
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
+               return -1;
+       }
+
+       client->speech_status = status;
+
+       ecore_main_loop_thread_safe_call_async(__stt_notify_speech_status, client);
+       return 0;
+}
+
 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
 {
        stt_client_s* client = NULL;
@@ -2190,3 +2231,54 @@ int stt_unset_engine_changed_cb(stt_h stt)
 
        return 0;
 }
+
+int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data)
+{
+       stt_client_s* client = NULL;
+       if (0 != __stt_get_feature_enabled()) {
+               return STT_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __stt_check_privilege()) {
+               return STT_ERROR_PERMISSION_DENIED;
+       }
+       if (0 != __stt_check_handle(stt, &client)) {
+               return STT_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == callback)
+               return STT_ERROR_INVALID_PARAMETER;
+
+       if (STT_STATE_CREATED != client->current_state) {
+               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
+               return STT_ERROR_INVALID_STATE;
+       }
+
+       client->speech_status_cb = callback;
+       client->speech_status_user_data = user_data;
+
+       return 0;
+}
+
+int stt_unset_speech_status_cb(stt_h stt)
+{
+       stt_client_s* client = NULL;
+       if (0 != __stt_get_feature_enabled()) {
+               return STT_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __stt_check_privilege()) {
+               return STT_ERROR_PERMISSION_DENIED;
+       }
+       if (0 != __stt_check_handle(stt, &client)) {
+               return STT_ERROR_INVALID_PARAMETER;
+       }
+
+       if (STT_STATE_CREATED != client->current_state) {
+               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
+               return STT_ERROR_INVALID_STATE;
+       }
+
+       client->speech_status_cb = NULL;
+       client->speech_status_user_data = NULL;
+
+       return 0;
+}
\ No newline at end of file
index e36e87e..793bfd7 100644 (file)
@@ -68,6 +68,8 @@ int stt_client_new(stt_h* stt)
        client->error_user_data = NULL;
        client->default_lang_changed_cb = NULL;
        client->default_lang_changed_user_data = NULL;
+       client->speech_status_cb = NULL;
+       client->speech_status_user_data = NULL;
 
        client->current_engine_id = NULL;
        client->credential = NULL;
@@ -88,6 +90,8 @@ int stt_client_new(stt_h* stt)
 
        client->internal_state = STT_INTERNAL_STATE_NONE;
 
+       client->speech_status = -1;
+
        client->cb_ref_count = 0;
 
        g_client_list = g_list_append(g_client_list, client);
index 2a89e2f..20c35d8 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <pthread.h>
 #include "stt.h"
+#include "stt_internal.h"
 #include "stt_main.h"
 
 #ifdef __cplusplus
@@ -55,6 +56,9 @@ typedef struct {
        stt_supported_language_cb       supported_lang_cb;
        void*                           supported_lang_user_data;
 
+       stt_speech_status_cb            speech_status_cb;
+       void*                           speech_status_user_data;
+
        char*           current_engine_id;
        char*           credential;
 
@@ -69,6 +73,9 @@ typedef struct {
 
        stt_internal_state_e    internal_state;
 
+       /* speech status */
+       int     speech_status;
+
        /* mutex */
        int             cb_ref_count;
 
index 7337224..a143b71 100644 (file)
@@ -43,6 +43,8 @@ extern int __stt_cb_set_state(int uid, int state);
 
 extern int __stt_cb_set_volume(int uid, float volume);
 
+extern int __stt_cb_speech_status(int uid, int status);
+
 char* __stt_get_service_name(char* engine_id)
 {
        char* service_name = NULL;
@@ -587,6 +589,32 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle
                        SLOG(LOG_DEBUG, TAG_STTC, " ");
                } /* STTD_METHOD_ERROR */
 
+               else if (dbus_message_is_signal(msg, if_name, STTD_METHOD_SPEECH_STATUS)) {
+                       SLOG(LOG_DEBUG, TAG_STTC, "===== Speech status");
+                       int uid = 0;
+                       int status = -1;
+
+                       dbus_message_get_args(msg, &err,
+                               DBUS_TYPE_INT32, &uid,
+                               DBUS_TYPE_INT32, &status,
+                               DBUS_TYPE_INVALID);
+
+                       if (dbus_error_is_set(&err)) {
+                               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get arguments error (%s)", err.message);
+                               dbus_error_free(&err);
+                       }
+
+                       if (uid > 0 && status >= 0) {
+                               SLOG(LOG_DEBUG, TAG_STTC, "<<<< stt speech status : uid(%d), status(%d)", uid, status);
+                               __stt_cb_speech_status(uid, status);
+                       } else {
+                               SLOG(LOG_ERROR, TAG_STTC, "<<<< stt set status : invalid uid or status");
+                       }
+
+                       SLOG(LOG_DEBUG, TAG_STTC, "=====");
+                       SLOG(LOG_DEBUG, TAG_STTC, " ");
+               } /* STTD_METHOD_SPEECH_STATUS */
+
                else {
                        SLOG(LOG_DEBUG, TAG_STTC, "Message is NOT valid");
                        dbus_message_unref(msg);
index 08126c4..00f8522 100644 (file)
@@ -74,6 +74,7 @@ extern "C" {
 #define STTD_METHOD_HELLO              "sttd_method_hello"
 #define STTD_METHOD_SET_STATE          "sttd_method_set_state"
 #define STTD_METHOD_SET_VOLUME         "sttd_method_set_volume"
+#define STTD_METHOD_SPEECH_STATUS      "sttd_method_speech_status"
 
 
 /******************************************************************************************
index dfabff1..5bd87f7 100644 (file)
@@ -10,6 +10,7 @@ INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-file.pc" DESTINATION
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-setting.pc" DESTINATION ${LIBDIR}/pkgconfig)
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-engine.pc" DESTINATION ${LIBDIR}/pkgconfig)
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/stt.h" DESTINATION ${INCLUDEDIR})
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/stt_internal.h" DESTINATION ${INCLUDEDIR})
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/stt_file.h" DESTINATION ${INCLUDEDIR})
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/stt_setting.h" DESTINATION ${INCLUDEDIR})
 INSTALL(FILES "${CMAKE_BINARY_DIR}/include/stte.h" DESTINATION ${INCLUDEDIR})
diff --git a/include/stt_internal.h b/include/stt_internal.h
new file mode 100644 (file)
index 0000000..d0b0e70
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STT_INTERNAL_H__
+#define __STT_INTERNAL_H__
+
+#include <tizen.h>
+
+/**
+ * @file stt_internal.h
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define STT_SPEECH_STATUS_BEGINNING_POINT_DETECTED     0
+
+/**
+ * @brief Called when user speaking is detected.
+ *
+ * @param[in] stt The STT handle
+ * @param[in] status The speech status
+ * @param[in] user_data The user data passed from the callback registration function
+ *
+ * @pre An application registers callback function using stt_set_speech_status_cb().
+ *
+ * @see stt_set_speech_status_cb()
+ * @see stt_unset_speech_status_cb()
+ */
+typedef void (*stt_speech_status_cb)(stt_h stt, int status, void *user_data);
+
+
+/**
+ * @brief Registers a callback function to detect the speech status is changed.
+ * @since_tizen 3.0
+ * @privilege %http://tizen.org/privilege/recorder
+ *
+ * @param[in] stt The STT handle
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STT_ERROR_NONE Successful
+ * @retval #STT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STT_ERROR_INVALID_STATE Invalid state
+ * @retval #STT_ERROR_NOT_SUPPORTED STT NOT supported
+ * @retval #STT_ERROR_PERMISSION_DENIED Permission denied
+ *
+ * @pre The state should be #STT_STATE_CREATED.
+ *
+ * @see stt_speech_status_cb()
+ * @see stt_unset_speech_status_cb()
+*/
+int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 3.0
+ * @privilege %http://tizen.org/privilege/recorder
+ *
+ * @param[in] stt The STT handle
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STT_ERROR_NONE Successful
+ * @retval #STT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STT_ERROR_INVALID_STATE Invalid state
+ * @retval #STT_ERROR_NOT_SUPPORTED STT NOT supported
+ * @retval #STT_ERROR_PERMISSION_DENIED Permission denied
+ *
+ * @pre The state should be #STT_STATE_CREATED.
+ *
+ * @see stt_set_speech_status_cb()
+*/
+int stt_unset_speech_status_cb(stt_h stt);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __STT_INTERNAL_H__ */
+
index 5746a07..358d33b 100644 (file)
@@ -136,6 +136,7 @@ mkdir -p %{TZ_SYS_RO_SHARE}/voice/test
 %defattr(-,root,root,-)
 %{_libdir}/pkgconfig/stt.pc
 %{_includedir}/stt.h
+%{_includedir}/stt_internal.h
 
 %files file-devel
 %defattr(-,root,root,-)
index ac1ef00..c86aa5d 100644 (file)
@@ -197,6 +197,50 @@ int sttdc_send_set_state(int uid, int state)
        return 0;
 }
 
+int sttdc_send_speech_status(int uid, int status)
+{
+       int pid = sttd_client_get_pid(uid);
+
+       if (0 > pid) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
+               return -1;
+       }
+
+       char service_name[64];
+       memset(service_name, 0, 64);
+       snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
+
+       char target_if_name[128];
+       snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
+
+       DBusMessage* msg = NULL;
+       msg = dbus_message_new_signal(
+               STT_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */
+               target_if_name,                 /* interface name of the signal */
+               STTD_METHOD_SPEECH_STATUS);     /* name of the signal */
+
+       if (NULL == msg) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
+               return -1;
+       }
+
+       dbus_message_append_args(msg,
+               DBUS_TYPE_INT32, &uid,
+               DBUS_TYPE_INT32, &status,
+               DBUS_TYPE_INVALID);
+
+       if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send speech status message : Out Of Memory !");
+       } else {
+               SLOG(LOG_DEBUG, TAG_STTD, "<<<< Send speech status message : uid(%d), status(%d)", uid, status);
+               dbus_connection_flush(g_conn_sender);
+       }
+
+       dbus_message_unref(msg);
+
+       return 0;
+}
+
 int sttdc_send_result(int uid, int event, const char** data, int data_count, const char* result_msg)
 {
        int pid = sttd_client_get_pid(uid);
index 91d81af..1f0d656 100644 (file)
@@ -34,6 +34,8 @@ int sttdc_send_result(int uid, int event, const char** data, int data_count, con
 
 int sttdc_send_error_signal(int uid, int reason, const char *err_msg);
 
+int sttdc_send_speech_status(int uid, int status);
+
 
 #ifdef __cplusplus
 }
index ea462df..d2f0bf2 100644 (file)
@@ -335,6 +335,7 @@ int __server_speech_status_callback(stte_speech_status_e status, void *user_para
 
                if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
                        SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
+                       sttdc_send_speech_status(uid, status);
                } else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
                        SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
                        ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);