Send voice key status events according to configuration values 52/228052/3
authorJi-hoon Lee <dalton.lee@samsung.com>
Thu, 9 Jan 2020 02:14:27 +0000 (11:14 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 19 Mar 2020 08:05:41 +0000 (17:05 +0900)
This patch includes some future features.

Change-Id: I1448d2b871286f1ac071cacea5196951e622d40d
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
20 files changed:
inc/multi_assistant_config.h
inc/multi_assistant_main.h
inc/multi_assistant_service_client.h
inc/multi_assistant_service_plugin.h
inc/multi_wakeup_recognizer.h
plugins/wakeup-manager/dependency-default/inc/dependency_default.h
plugins/wakeup-manager/dependency-default/inc/dependency_default_button.h
plugins/wakeup-manager/dependency-default/src/dependency_default.cpp
plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp
plugins/wakeup-manager/inc/dependency_resolver.h
plugins/wakeup-manager/inc/wakeup_manager.h
plugins/wakeup-manager/inc/wakeup_manager_wrapper.h
plugins/wakeup-manager/src/dependency_resolver.cpp
plugins/wakeup-manager/src/wakeup_manager.cpp
plugins/wakeup-manager/src/wakeup_manager_wrapper.cpp
src/multi_assistant_config.c
src/multi_assistant_dbus.c
src/multi_assistant_dbus.h
src/multi_assistant_service.c
src/multi_assistant_service_plugin.c

index e0b9f20..a5810ac 100644 (file)
@@ -42,6 +42,8 @@ extern "C"
 #define MA_TAG_ASSISTANT_WAKEUP_WORD                   "wakeup-word"
 #define MA_TAG_ASSISTANT_WAKEUP_ENGINE_APPID   "wakeup-engine-appid"
 #define MA_TAG_ASSISTANT_CUSTOM_UI                             "custom-ui"
+#define MA_TAG_ASSISTANT_VOICE_KEY_SUPPORT_MODE        "voice-key-support-mode"
+#define MA_TAG_ASSISTANT_VOICE_KEY_TAP_DURATION        "voice-key-tap-duration"
 
 /**************************************************************************************
  *** Definitions for ETC
@@ -50,6 +52,18 @@ extern "C"
 
 #define MA_ASSISTANT_INFO              tzplatform_mkpath(TZ_USER_HOME, "share/.multiassistant/ma/1.0/assistant-info")
 
+#define VOICE_KEY_SUPPORT_MODE_STRING_NONE "none"
+#define VOICE_KEY_SUPPORT_MODE_STRING_PUSH_TO_TALK "push_to_talk"
+#define VOICE_KEY_SUPPORT_MODE_STRING_TAP_TO_TALK "tap_to_talk"
+#define VOICE_KEY_SUPPORT_MODE_STRING_ALL "all"
+
+typedef enum {
+       VOICE_KEY_SUPPORT_MODE_NONE,
+       VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK,
+       VOICE_KEY_SUPPORT_MODE_TAP_TO_TALK,
+       VOICE_KEY_SUPPORT_MODE_ALL,
+} VOICE_KEY_SUPPORT_MODE;
+
 typedef struct {
        const char* app_id;
        const char* name;
@@ -61,12 +75,11 @@ typedef struct {
        int cnt_lang;
        const char* wakeup_engine;
        bool custom_ui_option;
+       VOICE_KEY_SUPPORT_MODE voice_key_support_mode;
+       float voice_key_tap_duration;
 } ma_assistant_info_s;
 
-typedef int (*mas_config_assistant_info_cb)(const char* appid, const char* name, const char* icon_path,
-       const char* wakeup_list[], const char* wakeup_language[], int cnt_wakeup,
-       const char* supported_lang[], int cnt_lang,
-       const char* wakeup_engine, bool custom_ui_option, void* user_data);
+typedef int (*mas_config_assistant_info_cb)(ma_assistant_info_s* info, void* user_data);
 int mas_config_get_assistant_info(mas_config_assistant_info_cb callback, void* user_data);
 
 #ifdef __cplusplus
index 8adc1c0..81018ac 100644 (file)
@@ -83,6 +83,7 @@
 #define MAS_METHOD_SEND_PREPROCESSING_RESULT           "mas_method_send_preprocessing_result"
 #define MAS_METHOD_SEND_WAKEUP_ENGINE_COMMAND          "mas_method_send_wakeup_engine_command"
 #define MAS_METHOD_SERVICE_STATE_CHANGE                                "mas_method_service_state_change"
+#define MAS_METHOD_VOICE_KEY_STATUS_CHANGE                     "mas_method_voice_key_status_change"
 
 #define MAS_UI_METHOD_SEND_ASR_RESULT                          "mas_ui_method_send_asr_result"
 #define MAS_UI_METHOD_SEND_RESULT                                      "mas_ui_method_send_result"
index bba7085..be2e984 100644 (file)
@@ -27,6 +27,28 @@ extern "C" {
 
 #define MAX_APPID_LEN 255
 
+typedef enum {
+       CLIENT_LAUNCH_MODE_ACTIVATION,
+       CLIENT_LAUNCH_MODE_PRELAUNCH,
+} CLIENT_LAUNCH_MODE;
+
+typedef enum {
+       PREPROCESSING_STATE_NONE,
+       PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED,
+       PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED,
+       PREPROCESSING_STATE_PREPROCESSING_UTTERANCE,
+       PREPROCESSING_STATE_PREPROCESSING_FOLLOW_UP,
+} PREPROCESSING_STATE;
+
+typedef enum {
+       PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED,
+       PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED,
+       PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED,
+       PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED,
+       PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED,
+       PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED,
+} PREPROCESSING_STATE_EVENT;
+
 int mas_client_initialize(int pid);
 
 int mas_client_deinitialize(int pid);
@@ -57,6 +79,8 @@ int mas_client_set_preprocessing_allow_mode(int pid, int mode, const char* appid
 
 int mas_client_send_preprocessing_result(int pid, bool result);
 
+int mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status);
+
 int mas_ui_client_initialize(int pid);
 
 int mas_ui_client_deinitialize(int pid);
@@ -89,31 +113,12 @@ int mas_set_current_service_state(ma_service_state_e state);
 
 ma_service_state_e mas_get_current_service_state();
 
-typedef enum {
-       CLIENT_LAUNCH_MODE_ACTIVATION,
-       CLIENT_LAUNCH_MODE_PRELAUNCH,
-} CLIENT_LAUNCH_MODE;
 int mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode);
 
-typedef enum {
-       PREPROCESSING_STATE_NONE,
-       PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED,
-       PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED,
-       PREPROCESSING_STATE_PREPROCESSING_UTTERANCE,
-       PREPROCESSING_STATE_PREPROCESSING_FOLLOW_UP,
-} PREPROCESSING_STATE;
-
-typedef enum {
-       PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED,
-       PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED,
-       PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED,
-       PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED,
-       PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED,
-       PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED,
-} PREPROCESSING_STATE_EVENT;
-
 int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event);
 
+int mas_update_voice_key_support_mode();
+
 
 #ifdef __cplusplus
 }
index 4f431e6..db1b6df 100644 (file)
@@ -83,6 +83,10 @@ int multi_assistant_service_plugin_get_recording_audio_format(int* rate, int* ch
 
 int multi_assistant_service_plugin_get_recording_audio_source_type(char **type);
 
+int multi_assistant_service_plugin_set_voice_key_tap_duration(float duration);
+
+int multi_assistant_service_plugin_unset_voice_key_tap_duration(void);
+
 int multi_assistant_service_plugin_set_callbacks(void);
 
 int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data);
@@ -151,6 +155,12 @@ typedef int (*wakeup_manager_stop_streaming_follow_up_data)(void);
 typedef int (*wakeup_manager_get_audio_format)(int* rate, int* channel, int* audio_type);
 #define MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_SOURCE_TYPE "wakeup_manager_get_audio_source_type"
 typedef int (*wakeup_manager_get_audio_source_type)(char** type);
+#define MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_TAP_DURATION "wakeup_manager_set_voice_key_tap_duration"
+typedef int (*wakeup_manager_set_voice_key_tap_duration)(float duration);
+#define MA_WAKEUP_MANAGER_FUNC_UNSET_VOICE_KEY_TAP_DURATION "wakeup_manager_unset_voice_key_tap_duration"
+typedef int (*wakeup_manager_unset_voice_key_tap_duration)();
+#define MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_SUPPORT_MODE "wakeup_manager_set_voice_key_support_mode"
+typedef int (*wakeup_manager_set_voice_key_support_mode)(int mode);
 #define MA_WAKEUP_MANAGER_FUNC_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG "wakeup_manager_set_wake_word_audio_require_flag"
 typedef int (*wakeup_manager_set_wake_word_audio_require_flag)(bool require);
 #define MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_LANGUAGE "wakeup_manager_set_assistant_language"
@@ -175,6 +185,8 @@ typedef int (*wakeup_manager_set_streaming_section_changed_callback)(wakeup_serv
 typedef int (*wakeup_manager_set_wakeup_engine_command_callback)(wakeup_service_wakeup_engine_command_cb callback, void* user_data);
 #define MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_SERVICE_STATE_CHANGED_CALLBACK "wakeup_manager_set_wakeup_service_state_changed_callback"
 typedef int (*wakeup_manager_set_wakeup_service_state_changed_callback)(wakeup_service_wakeup_service_state_changed_cb callback, void* user_data);
+#define MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_STATUS_CHANGED_CALLBACK "wakeup_manager_set_voice_key_status_changed_callback"
+typedef int (*wakeup_manager_set_voice_key_status_changed_callback)(wakeup_service_voice_key_status_changed_cb callback, void* user_data);
 
 typedef struct {
        wakeup_manager_initialize                                                                       initialize;
@@ -201,6 +213,9 @@ typedef struct {
        wakeup_manager_stop_streaming_follow_up_data                            stop_streaming_follow_up_data;
        wakeup_manager_get_audio_format                                                         get_audio_format;
        wakeup_manager_get_audio_source_type                                            get_audio_source_type;
+       wakeup_manager_set_voice_key_tap_duration                                       set_voice_key_tap_duration;
+       wakeup_manager_unset_voice_key_tap_duration                                     unset_voice_key_tap_duration;
+       wakeup_manager_set_voice_key_support_mode                                       set_voice_key_support_mode;
        wakeup_manager_set_wake_word_audio_require_flag                         set_wake_word_audio_require_flag;
        wakeup_manager_set_assistant_language                                           set_assistant_language;
        wakeup_manager_set_wakeup_event_callback                                        set_wakeup_event_callback;
@@ -213,6 +228,7 @@ typedef struct {
        wakeup_manager_set_streaming_section_changed_callback           set_streaming_section_changed_callback;
        wakeup_manager_set_wakeup_engine_command_callback                       set_wakeup_engine_command_callback;
        wakeup_manager_set_wakeup_service_state_changed_callback        set_wakeup_service_state_changed_callback;
+       wakeup_manager_set_voice_key_status_changed_callback            set_voice_key_status_changed_callback;
 } wakeup_manager_interface;
 
 #ifdef __cplusplus
index cdd8140..d5f8fb0 100644 (file)
@@ -44,6 +44,8 @@ typedef void (*wakeup_service_wakeup_engine_command_cb)(mas_wakeup_engine_comman
 
 typedef void (*wakeup_service_wakeup_service_state_changed_cb)(ma_service_state_e state, void* user_data);
 
+typedef void (*wakeup_service_voice_key_status_changed_cb)(ma_voice_key_status_e status, void* user_data);
+
 #ifdef __cplusplus
 }
 #endif
index bdd2b18..8469a64 100644 (file)
@@ -40,6 +40,8 @@ EXPORT_API int mas_dependency_set_background_volume(double ratio);
 EXPORT_API int mas_dependency_get_audio_format(int* rate, int* channel, int* audio_type);
 EXPORT_API int mas_dependency_get_audio_source_type(char** type);
 EXPORT_API int mas_dependency_process_wakeup_engine_command(const char* engine_name, const char* command);
+EXPORT_API int mas_dependency_set_voice_key_tap_duration(float duration);
+EXPORT_API int mas_dependency_unset_voice_key_tap_duration(void);
 
 #ifdef __cplusplus
 }
index 9c5b3c9..aa50c94 100644 (file)
@@ -21,5 +21,7 @@
 
 void dependency_default_button_initialize(mas_dependency_plugin_proxy_interface interface);
 void dependency_default_button_deinitialize();
+void dependency_default_button_set_voice_key_tap_duration(float duration);
+void dependency_default_button_unset_voice_key_tap_duration(void);
 
 #endif //_DEPENDENCY_DEFAULT_BUTTON_H_
index 7ca62bc..25f1252 100644 (file)
@@ -93,4 +93,16 @@ int mas_dependency_process_wakeup_engine_command(const char* engine_name, const
 {
        LOGD("Wakeup Engine %s has sent a command : %s", engine_name, command);
        return 0;
+}
+
+int mas_dependency_set_voice_key_tap_duration(float duration)
+{
+       dependency_default_button_set_voice_key_tap_duration(duration);
+       return 0;
+}
+
+int mas_dependency_unset_voice_key_tap_duration(void)
+{
+       dependency_default_button_unset_voice_key_tap_duration();
+       return 0;
 }
\ No newline at end of file
index 3b85756..f3684a8 100644 (file)
@@ -16,8 +16,10 @@ static mas_dependency_plugin_proxy_interface g_proxy_interface;
 static Ecore_Event_Handler* g_key_down_handler = NULL;
 static Ecore_Event_Handler* g_key_up_handler = NULL;
 
-static chrono::time_point<chrono::system_clock> g_last_time_point;
+static chrono::time_point<chrono::system_clock> g_last_key_pressed;
 static bool g_voice_key_pressed = false;
+const float DEFAULT_KEY_TAP_DURATION = 0.3f * 1000;
+static float g_voice_key_tap_duration = DEFAULT_KEY_TAP_DURATION;
 
 #define VOICE_KEY "XF86AudioPlayPause"
 
@@ -30,7 +32,7 @@ static Eina_Bool _key_down_cb(void* data, int type, void* event)
                if (ev->keyname && strncmp(ev->keyname, VOICE_KEY, strlen(VOICE_KEY)) == 0 ) {
                        chrono::time_point<chrono::system_clock> current_time_point;
                        current_time_point = chrono::system_clock::now();
-                       auto diff = current_time_point - g_last_time_point;
+                       auto diff = current_time_point - g_last_key_pressed;
                        auto milliseconds = chrono::duration_cast<chrono::milliseconds>(diff).count();
                        /* If double click detected within 500 msec */
                        if (milliseconds < 500) {
@@ -39,7 +41,7 @@ static Eina_Bool _key_down_cb(void* data, int type, void* event)
                                        g_voice_key_pressed = true;
                                }
                        }
-                       g_last_time_point = current_time_point;
+                       g_last_key_pressed = current_time_point;
                }
        }
 
@@ -54,7 +56,17 @@ static Eina_Bool _key_up_cb(void* data, int type, void* event)
 
                if (g_voice_key_pressed &&
                        ev->keyname && strncmp(ev->keyname, VOICE_KEY, strlen(VOICE_KEY)) == 0) {
-                       mas_plugin_event_e event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH;
+                       chrono::time_point<chrono::system_clock> current_time_point;
+                       current_time_point = chrono::system_clock::now();
+                       auto diff = current_time_point - g_last_key_pressed;
+                       auto milliseconds = chrono::duration_cast<chrono::milliseconds>(diff).count();
+                       LOGD("milliseconds : %lld", milliseconds);
+                       mas_plugin_event_e event;
+                       if (milliseconds < g_voice_key_tap_duration) {
+                               event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP;
+                       } else {
+                               event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH;
+                       }
                        if (g_proxy_interface.process_event) {
                                g_proxy_interface.process_event(event, NULL, 0);
                        }
@@ -129,7 +141,7 @@ void dependency_default_button_initialize(mas_dependency_plugin_proxy_interface
        _ecore_wl2_display = ecore_wl2_display_connect(NULL);
        LOGD("_ecore_wl2_display: %p", _ecore_wl2_display);
 
-       g_last_time_point = chrono::system_clock::now();
+       g_last_key_pressed = chrono::system_clock::now();
        _grab_voice_key();
        _add_key_cb();
 }
@@ -138,4 +150,14 @@ void dependency_default_button_deinitialize()
 {
        _delete_key_cb();
        _ungrab_voice_key();
+}
+
+void dependency_default_button_set_voice_key_tap_duration(float duration)
+{
+       g_voice_key_tap_duration = duration * 1000.0f; // in milliseconds
+}
+
+void dependency_default_button_unset_voice_key_tap_duration(void)
+{
+       g_voice_key_tap_duration = DEFAULT_KEY_TAP_DURATION;
 }
\ No newline at end of file
index 75d882e..1804803 100644 (file)
@@ -54,6 +54,11 @@ typedef int (*mas_dependency_get_audio_source_type)(char** type);
 typedef int (*mas_dependency_process_wakeup_engine_command)(const char* engine_name, const char* command);
 #define MAS_DEPENDENCY_FUNC_PROCESS_WAKEUP_CANDIDATE "mas_dependency_process_wakeup_candidate"
 typedef int (*mas_dependency_process_wakeup_candidate)(const mas_wakeup_event_info* info);
+#define MAS_DEPENDENCY_FUNC_SET_VOICE_KEY_TAP_DURATION "mas_dependency_set_voice_key_tap_duration"
+typedef int (*mas_dependency_set_voice_key_tap_duration)(float duration);
+#define MAS_DEPENDENCY_FUNC_UNSET_VOICE_KEY_TAP_DURATION "mas_dependency_unset_voice_key_tap_duration"
+typedef int (*mas_dependency_unset_voice_key_tap_duration)(void);
+
 
 typedef struct {
        mas_dependency_initialize                                                               initialize;
@@ -67,6 +72,8 @@ typedef struct {
        mas_dependency_get_audio_source_type                                    get_audio_source_type;
        mas_dependency_process_wakeup_engine_command                    process_wakeup_engine_command;
        mas_dependency_process_wakeup_candidate                                 process_wakeup_candidate;
+       mas_dependency_set_voice_key_tap_duration                               set_voice_key_tap_duration;
+       mas_dependency_unset_voice_key_tap_duration                             unset_voice_key_tap_duration;
 } mas_dependency_module_interface;
 
 int dependency_resolver_initialize(mas_dependency_plugin_proxy_interface interface);
@@ -80,6 +87,8 @@ int dependency_resolver_get_audio_format(int* rate, int* channel, int* audio_typ
 int dependency_resolver_get_audio_source_type(char** type);
 int dependency_resolver_process_wakeup_engine_command(const char* engine, const char* command);
 int dependency_resolver_process_wakeup_candidate(mas_wakeup_event_info* info);
+int dependency_resolver_set_voice_key_tap_duration(float duration);
+int dependency_resolver_unset_voice_key_tap_duration();
 
 mas_dependency_module_interface* dependency_resolver_get_interface();
 
index b010453..0f2d6ed 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef _WAKEUP_MANAGER_H_
 #define _WAKEUP_MANAGER_H_
 
+#include "multi_assistant_config.h"
 #include "wakeup_manager_wrapper.h"
 #include "wakeup_settings.h"
 #include "wakeup_engine_manager.h"
@@ -52,6 +53,7 @@ public:
        virtual void on_wakeup_engine_command(
                mas_wakeup_engine_command_target_e target, const char* name, const char* command) = 0;
        virtual void on_wakeup_service_state_changed(ma_service_state_e state) = 0;
+       virtual void on_voice_key_status_changed(ma_voice_key_status_e status) = 0;
 };
 
 class ISettingValueObserver {
@@ -104,6 +106,9 @@ public:
        bool get_audio_source_type(char** type);
        bool set_language(string language);
        bool get_voice_key_pressed();
+       bool set_voice_key_tap_duration(float duration);
+       bool unset_voice_key_tap_duration();
+       bool set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE mode);
        bool set_wake_word_audio_require_flag(bool require);
 
        STREAMING_MODE get_streaming_mode();
@@ -132,6 +137,8 @@ public:
        void feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len);
        void set_dependency_module_command(string engine_name, string command);
 private:
+       bool change_voice_key_status(ma_voice_key_status_e status);
+
        class CEngineEventObserver : public IEngineEventObserver
        {
        public:
@@ -218,6 +225,7 @@ private:
        bool mVoiceKeyPressed{false};
        string mCurrentLanguage;
        string mCurrentDefaultAssistant;
+       VOICE_KEY_SUPPORT_MODE mCurrentVoiceKeySupportMode;
 
        STREAMING_MODE mStreamingMode{STREAMING_MODE::NONE};
        Ecore_Timer* mStreamingDurationTimer{nullptr};
index 7857664..cdcaa08 100644 (file)
@@ -58,6 +58,8 @@ typedef void (*wakeup_service_engine_command_cb)(mas_wakeup_engine_command_targe
 
 typedef void (*wakeup_service_state_changed_cb)(ma_service_state_e state, void* user_data);
 
+typedef void (*wakeup_service_voice_key_status_changed_cb)(ma_voice_key_status_e state, void* user_data);
+
 typedef struct {
        int plugin_version;
        bool ui_panel_enabled;
@@ -111,6 +113,12 @@ EXPORT_API int wakeup_manager_get_audio_format(int *rate, int *channel, int *aud
 
 EXPORT_API int wakeup_manager_get_audio_source_type(char** type);
 
+EXPORT_API int wakeup_manager_set_voice_key_tap_duration(float duration);
+
+EXPORT_API int wakeup_manager_unset_voice_key_tap_duration();
+
+EXPORT_API int wakeup_manager_set_voice_key_support_mode(int mode);
+
 EXPORT_API int wakeup_manager_set_wake_word_audio_require_flag(bool require);
 
 EXPORT_API int wakeup_manager_set_assistant_language(const char* appid, const char *language);
@@ -135,6 +143,8 @@ EXPORT_API int wakeup_manager_set_wakeup_engine_command_callback(wakeup_service_
 
 EXPORT_API int wakeup_manager_set_wakeup_service_state_changed_callback(wakeup_service_state_changed_cb callback, void* user_data);
 
+EXPORT_API int wakeup_manager_set_voice_key_status_changed_callback(wakeup_service_voice_key_status_changed_cb callback, void* user_data);
+
 /* Internal API declarations for dependency modules */
 
 int wakeup_manager_feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len);
index c2537d6..3b2ef19 100644 (file)
@@ -97,6 +97,12 @@ int dependency_resolver_initialize(mas_dependency_plugin_proxy_interface interfa
        g_mas_dependency.process_wakeup_candidate =
                (mas_dependency_process_wakeup_candidate)dlsym(g_handle,
                MAS_DEPENDENCY_FUNC_PROCESS_WAKEUP_CANDIDATE);
+       g_mas_dependency.set_voice_key_tap_duration =
+               (mas_dependency_set_voice_key_tap_duration)dlsym(g_handle,
+               MAS_DEPENDENCY_FUNC_SET_VOICE_KEY_TAP_DURATION);
+       g_mas_dependency.unset_voice_key_tap_duration =
+               (mas_dependency_unset_voice_key_tap_duration)dlsym(g_handle,
+               MAS_DEPENDENCY_FUNC_UNSET_VOICE_KEY_TAP_DURATION);
 
        int ret = -1;
        int dependency_version = 0;
@@ -377,3 +383,53 @@ int dependency_resolver_process_wakeup_candidate(mas_wakeup_event_info* info)
 
        return ret;
 }
+
+int dependency_resolver_set_voice_key_tap_duration(float duration)
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               mas_dependency_set_voice_key_tap_duration func = g_mas_dependency.set_voice_key_tap_duration;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MAS_DEPENDENCY_FUNC_SET_VOICE_KEY_TAP_DURATION);
+               } else {
+                       try {
+                               ret = func(duration);
+                       } catch (const std::exception& e) {
+                               MAS_LOGE("[ERROR] %s of dependency module threw exception : %s",
+                                       MAS_DEPENDENCY_FUNC_SET_VOICE_KEY_TAP_DURATION, e.what());
+                       }
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to set voice key tap duration to %f, ret(%d)", duration, ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+
+       return ret;
+}
+
+int dependency_resolver_unset_voice_key_tap_duration()
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               mas_dependency_unset_voice_key_tap_duration func = g_mas_dependency.unset_voice_key_tap_duration;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MAS_DEPENDENCY_FUNC_UNSET_VOICE_KEY_TAP_DURATION);
+               } else {
+                       try {
+                               ret = func();
+                       } catch (const std::exception& e) {
+                               MAS_LOGE("[ERROR] %s of dependency module threw exception : %s",
+                                       MAS_DEPENDENCY_FUNC_UNSET_VOICE_KEY_TAP_DURATION, e.what());
+                       }
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to unset voice key tap duration, ret(%d)", ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+
+       return ret;
+}
\ No newline at end of file
index 846db1b..ab2b8a4 100644 (file)
@@ -488,75 +488,94 @@ static long long get_current_milliseconds_after_epoch()
        return value.count();
 }
 
+bool CWakeupManager::change_voice_key_status(ma_voice_key_status_e status) {
+       for (const auto& observer : mWakeupObservers) {
+               observer->on_voice_key_status_changed(status);
+       }
+       if (MA_VOICE_KEY_STATUS_PRESSED == status) {
+               mVoiceKeyPressed = true;
+       } else if (
+               MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH == status ||
+               MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP == status) {
+               mVoiceKeyPressed = false;
+       }
+}
+
 bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len)
 {
        MWR_LOGD("[ENTER] : %d", event);
        if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
                return false;
 
-       // LOCK REQUIRED
+       bool start_recording = false;
+       bool stop_recording = false;
+
        if (MAS_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) {
-               if (mVoiceKeyPressed != true) {
-                       mAudioManager.stop_recording(true);
+               if (VOICE_KEY_SUPPORT_MODE_NONE != mCurrentVoiceKeySupportMode) {
+                       start_recording = true;
+               }
+               change_voice_key_status(MA_VOICE_KEY_STATUS_PRESSED);
+       } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) {
+               if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode ||
+                       VOICE_KEY_SUPPORT_MODE_ALL == mCurrentVoiceKeySupportMode) {
+                       stop_recording = true;
+               }
+               change_voice_key_status(MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH);
+       } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
+               if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode) {
+                       stop_recording = true;
+               }
+               change_voice_key_status(MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP);
+       }
 
-                       stop_streaming_utterance_data();
-                       stop_streaming_previous_utterance_data();
-                       stop_streaming_follow_up_data();
+       if (start_recording) {
+               mAudioManager.stop_recording(true);
 
-                       mAudioManager.clear_audio_data();
-                       change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
+               stop_streaming_utterance_data();
+               stop_streaming_previous_utterance_data();
+               stop_streaming_follow_up_data();
 
-                       mVoiceKeyPressed = true;
+               mAudioManager.clear_audio_data();
+               change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
 
-                       /* Start recorder thread using appropriate recording device */
-                       mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
-                       mAudioManager.start_recording(true);
+               /* Start recorder thread using appropriate recording device */
+               mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
+               mAudioManager.start_recording(true);
 
-                       /* Wakeup default assistant */
-                       /* TODO: apply conversation timeout for selecting assistant here */
-                       mas_wakeup_event_info wakeup_info;
-                       initialize_wakeup_event_info(&wakeup_info);
-                       /* Make sure to use background data */
-                       wakeup_info.wakeup_time_valid = true;
-                       wakeup_info.wakeup_end_time = get_current_milliseconds_after_epoch();
-                       wakeup_info.wakeup_engine = WAKEUP_ENGINE_VOICE_KEY;
-
-                       string appid = mWakeupSettings.get_default_assistant_appid();
-                       wakeup_info.wakeup_appid = appid.c_str();
-                       MWR_LOGD("wakeup_appid : %s", wakeup_info.wakeup_appid);
-
-                       set_last_wakeup_event_info(wakeup_info);
-                       mWakeupEngineManager.set_selected_wakeup_info(wakeup_info);
-                       for (const auto& observer : mWakeupObservers) {
-                               observer->on_wakeup(wakeup_info);
-                       }
+               /* Wakeup default assistant */
+               /* TODO: apply conversation timeout for selecting assistant here */
+               mas_wakeup_event_info wakeup_info;
+               initialize_wakeup_event_info(&wakeup_info);
+               /* Make sure to use background data */
+               wakeup_info.wakeup_time_valid = true;
+               wakeup_info.wakeup_end_time = get_current_milliseconds_after_epoch();
+               wakeup_info.wakeup_engine = WAKEUP_ENGINE_VOICE_KEY;
+
+               wakeup_info.wakeup_appid = mCurrentDefaultAssistant.c_str();
+               MWR_LOGD("wakeup_appid : %s", wakeup_info.wakeup_appid);
+
+               set_last_wakeup_event_info(wakeup_info);
+               mWakeupEngineManager.set_selected_wakeup_info(wakeup_info);
+               for (const auto& observer : mWakeupObservers) {
+                       observer->on_wakeup(wakeup_info);
                }
-       } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) {
-               if (mVoiceKeyPressed != false) {
-                       mAudioManager.finalize_audio_data();
-                       mVoiceKeyPressed = false;
-
-                       if (STREAMING_MODE::UTTERANCE == mStreamingMode) {
-                               change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
-                       } else {
-                               change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
-                       }
+       }
+       if (stop_recording) {
+               mAudioManager.finalize_audio_data();
 
-                       if (mWakeupEngineManager.get_audio_data_required()) {
-                               /* Restart recorder thread using appropriate recording device */
-                               mAudioManager.stop_recording(true);
-                               mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
-                               mAudioManager.start_recording(true);
-                       } else {
-                               mAudioManager.stop_recording(true);
-                       }
+               if (STREAMING_MODE::UTTERANCE == mStreamingMode) {
+                       change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
+               } else {
+                       change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
                }
-       } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
-               if (mVoiceKeyPressed != false) {
-                       mVoiceKeyPressed = false;
+
+               mAudioManager.stop_recording(true);
+               mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
+               if (mWakeupEngineManager.get_audio_data_required()) {
+                       /* Restart recorder thread using appropriate recording device */
+                       mAudioManager.start_recording(true);
                }
        }
-       // UNLOCK REQUIRED
 
        MWR_LOGD("[END]");
        return true;
@@ -830,6 +849,32 @@ bool CWakeupManager::set_wake_word_audio_require_flag(bool require)
        return true;
 }
 
+bool CWakeupManager::set_voice_key_tap_duration(float duration)
+{
+       MWR_LOGD("[ENTER]");
+
+       dependency_resolver_set_voice_key_tap_duration(duration);
+
+       MWR_LOGD("[END]");
+       return true;
+}
+
+bool CWakeupManager::unset_voice_key_tap_duration()
+{
+       MWR_LOGD("[ENTER]");
+
+       dependency_resolver_unset_voice_key_tap_duration();
+
+       MWR_LOGD("[END]");
+       return true;
+}
+
+bool CWakeupManager::set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE mode)
+{
+       mCurrentVoiceKeySupportMode = mode;
+       return true;
+}
+
 CWakeupPolicy* CWakeupManager::get_wakeup_policy()
 {
        return mWakeupPolicy.get();
index 5e0b31a..b2395e5 100644 (file)
@@ -51,6 +51,9 @@ static void* g_wakeup_engine_command_user_data;
 static wakeup_service_state_changed_cb g_wakeup_service_state_changed_cb;
 static void *g_wakeup_service_state_changed_user_data;
 
+static wakeup_service_voice_key_status_changed_cb g_wakeup_service_voice_key_status_changed_cb;
+static void *g_wakeup_service_voice_key_status_changed_user_data;
+
 class CWakeupEventObserver : public IWakeupEventObserver
 {
        void on_wakeup(mas_wakeup_event_info wakeup_info) override;
@@ -60,6 +63,7 @@ class CWakeupEventObserver : public IWakeupEventObserver
        void on_wakeup_engine_command(
                mas_wakeup_engine_command_target_e target, const char* assistant_name, const char* command) override;
        void on_wakeup_service_state_changed(ma_service_state_e state) override;
+       void on_voice_key_status_changed(ma_voice_key_status_e status) override;
 };
 
 class CSettingValueObserver : public ISettingValueObserver
@@ -117,6 +121,9 @@ int wakeup_manager_initialize(void)
        g_wakeup_service_state_changed_cb = NULL;
        g_wakeup_service_state_changed_user_data = NULL;
 
+       g_wakeup_service_voice_key_status_changed_cb = NULL;
+       g_wakeup_service_voice_key_status_changed_user_data = NULL;
+
        g_wakeup_manager->initialize();
 
        MWR_LOGD("[END]");
@@ -476,6 +483,39 @@ int wakeup_manager_get_audio_source_type(char** type)
        return 0;
 }
 
+int wakeup_manager_set_voice_key_tap_duration(float duration)
+{
+       MWR_LOGD("[ENTER]");
+
+       if (nullptr == g_wakeup_manager) return -1;
+       g_wakeup_manager->set_voice_key_tap_duration(duration);
+
+       MWR_LOGD("[END] duration(%f)", duration);
+       return 0;
+}
+
+int wakeup_manager_unset_voice_key_tap_duration()
+{
+       MWR_LOGD("[ENTER]");
+
+       if (nullptr == g_wakeup_manager) return -1;
+       g_wakeup_manager->unset_voice_key_tap_duration();
+
+       MWR_LOGD("[END]");
+       return 0;
+}
+
+int wakeup_manager_set_voice_key_support_mode(int mode)
+{
+       MWR_LOGD("[ENTER] : %d", mode);
+
+       if (nullptr == g_wakeup_manager) return -1;
+       g_wakeup_manager->set_voice_key_support_mode(static_cast<VOICE_KEY_SUPPORT_MODE>(mode));
+
+       MWR_LOGD("[END]");
+       return 0;
+}
+
 int wakeup_manager_set_wake_word_audio_require_flag(bool require)
 {
        MWR_LOGD("[ENTER] : %d", require);
@@ -667,6 +707,22 @@ int wakeup_manager_set_wakeup_service_state_changed_callback(wakeup_service_stat
        return 0;
 }
 
+int wakeup_manager_set_voice_key_status_changed_callback(wakeup_service_voice_key_status_changed_cb callback, void* user_data)
+{
+       MWR_LOGD("[ENTER]");
+
+       if (NULL == callback) {
+               MWR_LOGE("[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       g_wakeup_service_voice_key_status_changed_cb = callback;
+       g_wakeup_service_voice_key_status_changed_user_data = user_data;
+
+       MWR_LOGD("[END]");
+       return 0;
+}
+
 int wakeup_manager_feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len)
 {
        if (nullptr == g_wakeup_manager) return -1;
@@ -736,6 +792,13 @@ void CWakeupEventObserver::on_wakeup_service_state_changed(ma_service_state_e st
        }
 }
 
+void CWakeupEventObserver::on_voice_key_status_changed(ma_voice_key_status_e status)
+{
+       if (g_wakeup_service_voice_key_status_changed_cb) {
+               g_wakeup_service_voice_key_status_changed_cb(status, g_wakeup_service_voice_key_status_changed_user_data);
+       }
+}
+
 void CSettingValueObserver::on_value_changed()
 {
        if (g_setting_changed_cb) {
index 5e7dd0f..c138d89 100644 (file)
@@ -65,24 +65,21 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
        }
 
        /* alloc assistant info */
-       ma_assistant_info_s* temp;
-       temp = (ma_assistant_info_s*)calloc(1, sizeof(ma_assistant_info_s));
-       if (NULL == temp) {
-               MAS_LOGE("[ERROR] Fail to allocate memory");
-               xmlFreeDoc(doc);
-               return -1;
-       }
-
-       temp->app_id = NULL;
-       temp->name = NULL;
-       temp->icon_path = NULL;
-       memset(temp->wakeup_list, 0x00, sizeof(temp->wakeup_list));
-       memset(temp->wakeup_language, 0x00, sizeof(temp->wakeup_language));
-       temp->cnt_wakeup = 0;
-       memset(temp->supported_lang, 0x00, sizeof(temp->supported_lang));
-       temp->cnt_lang = 0;
-       temp->wakeup_engine = NULL;
-       temp->custom_ui_option = false;
+       ma_assistant_info_s temp;
+
+       temp.app_id = NULL;
+       temp.name = NULL;
+       temp.icon_path = NULL;
+       memset(temp.wakeup_list, 0x00, sizeof(temp.wakeup_list));
+       memset(temp.wakeup_language, 0x00, sizeof(temp.wakeup_language));
+       temp.cnt_wakeup = 0;
+       memset(temp.supported_lang, 0x00, sizeof(temp.supported_lang));
+       temp.cnt_lang = 0;
+       temp.wakeup_engine = NULL;
+       temp.custom_ui_option = false;
+       /* TODO: Define these two default values somewhere else */
+       temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK;
+       temp.voice_key_tap_duration = 0.0f; /* Meaning not set */
 
        while (cur != NULL) {
                if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar *)MA_TAG_ASSISTANT_LANGUAGE_SET)) {
@@ -91,7 +88,7 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
                                if (child_node->name && 0 == xmlStrcmp(child_node->name, (const xmlChar*)MA_TAG_ASSISTANT_LANGUAGE)) {
                                        key = xmlNodeGetContent(child_node);
                                        if (key) {
-                                               temp->supported_lang[temp->cnt_lang++] = strdup((const char*)key);
+                                               temp.supported_lang[temp.cnt_lang++] = strdup((const char*)key);
                                                MAS_LOGD("Language : %s", key);
                                                xmlFree(key);
                                        }
@@ -105,17 +102,17 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
                                if (child_node->name && 0 == xmlStrcmp(child_node->name, (const xmlChar*)MA_TAG_ASSISTANT_WAKEUP_WORD)) {
                                        key = xmlNodeGetContent(child_node);
                                        if (key) {
-                                               temp->wakeup_list[temp->cnt_wakeup] = strdup((const char*)key);
+                                               temp.wakeup_list[temp.cnt_wakeup] = strdup((const char*)key);
                                                MAS_LOGD("Wakeup Word : %s", key);
                                                xmlFree(key);
                                        }
                                        xmlChar* prop = xmlNodeGetLang(child_node);
                                        if (prop) {
-                                               temp->wakeup_language[temp->cnt_wakeup] = strdup((const char*)prop);
-                                               MAS_LOGD("Wakeup Language for %s : %s", temp->wakeup_list[temp->cnt_wakeup], prop);
+                                               temp.wakeup_language[temp.cnt_wakeup] = strdup((const char*)prop);
+                                               MAS_LOGD("Wakeup Language for %s : %s", temp.wakeup_list[temp.cnt_wakeup], prop);
                                                xmlFree(prop);
                                        }
-                                       temp->cnt_wakeup++;
+                                       temp.cnt_wakeup++;
                                }
 
                                child_node = child_node->next;
@@ -123,28 +120,28 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
                } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_NAME)) {
                        key = xmlNodeGetContent(cur);
                        if (key) {
-                               temp->name = strdup((const char*)key);
+                               temp.name = strdup((const char*)key);
                                MAS_LOGD("Name : %s", key);
                                xmlFree(key);
                        }
                } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_APPID)) {
                        key = xmlNodeGetContent(cur);
                        if (key) {
-                               temp->app_id = strdup((const char*)key);
+                               temp.app_id = strdup((const char*)key);
                                MAS_LOGD("ID : %s", key);
                                xmlFree(key);
                        }
                } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_ICON_PATH)) {
                        key = xmlNodeGetContent(cur);
                        if (key) {
-                               temp->icon_path = strdup((const char*)key);
+                               temp.icon_path = strdup((const char*)key);
                                MAS_LOGD("Icon Path : %s", key);
                                xmlFree(key);
                        }
                } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_WAKEUP_ENGINE_APPID)) {
                        key = xmlNodeGetContent(cur);
                        if (key) {
-                               temp->wakeup_engine = strdup((const char*)key);
+                               temp.wakeup_engine = strdup((const char*)key);
                                MAS_LOGD("Wakeup Engine : %s", key);
                                xmlFree(key);
                        }
@@ -152,9 +149,31 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
                        key = xmlNodeGetContent(cur);
                        if (key) {
                                if (0 == xmlStrcasecmp(key, "true")) {
-                                       temp->custom_ui_option = true;
+                                       temp.custom_ui_option = true;
                                }
-                               MAS_LOGD("Use custom UI : %d", temp->custom_ui_option);
+                               MAS_LOGD("Use custom UI : %d", temp.custom_ui_option);
+                               xmlFree(key);
+                       }
+               } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_VOICE_KEY_SUPPORT_MODE)) {
+                       key = xmlNodeGetContent(cur);
+                       if (key) {
+                               if (xmlStrcmp(cur->name, (const xmlChar*)VOICE_KEY_SUPPORT_MODE_STRING_ALL)) {
+                                       temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_ALL;
+                               } else if (xmlStrcmp(cur->name, (const xmlChar*)VOICE_KEY_SUPPORT_MODE_STRING_TAP_TO_TALK)) {
+                                       temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_TAP_TO_TALK;
+                               } else if (xmlStrcmp(cur->name, (const xmlChar*)VOICE_KEY_SUPPORT_MODE_STRING_PUSH_TO_TALK)) {
+                                       temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK;
+                               } else {
+                                       temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_NONE;
+                               }
+                               MAS_LOGD("Voice key support mode : %s", cur->name);
+                               xmlFree(key);
+                       }
+               } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_VOICE_KEY_TAP_DURATION)) {
+                       key = xmlNodeGetContent(cur);
+                       if (key) {
+                               temp.voice_key_tap_duration = atof((const char*)key);
+                               MAS_LOGD("Voice key tap duration : %s", key);
                                xmlFree(key);
                        }
                }
@@ -163,36 +182,32 @@ int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const
        }
 
        if (callback) {
-               callback(temp->app_id, temp->name, temp->icon_path,
-                       temp->wakeup_list, temp->wakeup_language, temp->cnt_wakeup,
-                       temp->supported_lang, temp->cnt_lang,
-                       temp->wakeup_engine, temp->custom_ui_option, user_data);
+               callback(&temp, user_data);
        }
 
-       if (temp->app_id) {
-               free((void*)temp->app_id);
+       if (temp.app_id) {
+               free((void*)temp.app_id);
        }
-       if (temp->name) {
-               free((void*)temp->name);
+       if (temp.name) {
+               free((void*)temp.name);
        }
-       if (temp->icon_path) {
-               free((void*)temp->icon_path);
+       if (temp.icon_path) {
+               free((void*)temp.icon_path);
        }
-       for (loop = 0; loop < temp->cnt_wakeup; loop++) {
-               if (temp->wakeup_list[loop]) {
-                       free((void*)(temp->wakeup_list[loop]));
+       for (loop = 0; loop < temp.cnt_wakeup; loop++) {
+               if (temp.wakeup_list[loop]) {
+                       free((void*)(temp.wakeup_list[loop]));
                }
        }
-       for (loop = 0; loop < temp->cnt_lang; loop++) {
-               if (temp->supported_lang[loop]) {
-                       free((void*)(temp->supported_lang[loop]));
+       for (loop = 0; loop < temp.cnt_lang; loop++) {
+               if (temp.supported_lang[loop]) {
+                       free((void*)(temp.supported_lang[loop]));
                }
        }
-       if (temp->wakeup_engine) {
-               free((void*)temp->wakeup_engine);
+       if (temp.wakeup_engine) {
+               free((void*)temp.wakeup_engine);
        }
 
-       free(temp);
        xmlFreeDoc(doc);
 
        return 0;
index a09d82d..a7f567c 100644 (file)
@@ -592,7 +592,58 @@ int masc_dbus_service_state_change(int pid, int state)
                MAS_LOGE("[Dbus ERROR] Fail to Send");
                return -1; // MAS_ERROR_OPERATION_FAILED;
        } else {
-               MAS_LOGI("[Dbus DEBUG] Success to Send activate message : %d %d", pid, state);
+               MAS_LOGI("[Dbus DEBUG] Success to Send service state message : %d %d", pid, state);
+               dbus_connection_flush(g_conn_sender);
+       }
+
+       dbus_message_unref(msg);
+       return 0;
+}
+
+int masc_dbus_voice_key_status_change(int pid, int status)
+{
+       if (0 != __dbus_check()) {
+               return -1; //MAS_ERROR_OPERATION_FAILED;
+       }
+
+       DBusMessage* msg;
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+       msg = dbus_message_new_method_call(
+                       service_name,
+                       MA_CLIENT_SERVICE_OBJECT_PATH,
+                       MA_CLIENT_SERVICE_INTERFACE,
+                       MAS_METHOD_VOICE_KEY_STATUS_CHANGE);
+
+       static int count = 0;
+       if (NULL == msg) {
+               MAS_LOGE(">>>> Request mas send voice key status change message : Fail to make message");
+               return -1; // MAS_ERROR_OPERATION_FAILED;
+       } else {
+               MAS_LOGD(">>>> Request mas send voice key status change message : %s", service_name);
+       }
+
+       if (true != dbus_message_append_args(msg,
+               DBUS_TYPE_INT32, &status,
+               DBUS_TYPE_INVALID)) {
+               dbus_message_unref(msg);
+               MAS_LOGE("[ERROR] Fail to append args");
+               return -1;
+       }
+
+       dbus_message_set_no_reply(msg, TRUE);
+
+       if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+               MAS_LOGE("[Dbus ERROR] Fail to Send");
+               return -1; // MAS_ERROR_OPERATION_FAILED;
+       } else {
+               MAS_LOGI("[Dbus DEBUG] Success to Send voice key status change : %d %d", pid, status);
                dbus_connection_flush(g_conn_sender);
        }
 
index 4c38cd2..5fa9681 100644 (file)
@@ -43,6 +43,8 @@ int masc_dbus_send_wakeup_engine_command(int pid, const char* command);
 
 int masc_dbus_service_state_change(int pid, int state);
 
+int masc_dbus_voice_key_status_change(int pid, int status);
+
 int masc_ui_dbus_send_hello(void);
 
 int masc_ui_dbus_send_asr_result(int pid, int event, char* asr_result);
index 72ef66f..14ed502 100644 (file)
@@ -57,6 +57,8 @@ typedef struct {
        char wakeup_engine[MAX_APPID_LEN];
        char supported_language[MAX_SUPPORTED_LANGUAGES_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
        bool custom_ui_option;
+       VOICE_KEY_SUPPORT_MODE voice_key_support_mode;
+       float voice_key_tap_duration;
 
        ma_preprocessing_allow_mode_e preprocessing_allow_mode;
        char preprocessing_allow_appid[MAX_APPID_LEN];
@@ -76,6 +78,7 @@ static package_manager_h g_pkgmgr = NULL;
 
 static PREPROCESSING_STATE g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
 static ma_service_state_e g_current_service_state = MA_SERVICE_STATE_INACTIVE;
+static ma_voice_key_status_e g_last_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH;
 
 /* client list */
 static GSList* g_client_list = NULL;
@@ -245,6 +248,9 @@ int mas_client_initialize(int pid)
                }
 
                mas_client_send_preprocessing_information(pid);
+               if (MA_VOICE_KEY_STATUS_PRESSED == g_last_voice_key_status) {
+                       mas_client_send_voice_key_status_change(pid, g_last_voice_key_status);
+               }
                if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) {
                        MAS_LOGD("MA client with current maclient appid connected!");
 
@@ -327,6 +333,16 @@ int mas_client_send_preprocessing_information(int pid)
        return ret;
 }
 
+int mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status)
+{
+       g_last_voice_key_status = status;
+       int ret = masc_dbus_voice_key_status_change(pid, status);
+       if (0 != ret) {
+               MAS_LOGE("[ERROR] Fail to send voice key status changed information, ret(%d)", ret);
+       }
+       return ret;
+}
+
 int mas_client_activate(int pid)
 {
        int ret = -1;
@@ -588,6 +604,10 @@ int mas_ui_client_change_assistant(const char* appid)
        if (pid != -1) {
                mas_bring_client_to_foreground(appid);
                mas_client_send_preprocessing_information(pid);
+               if (MA_VOICE_KEY_STATUS_PRESSED == g_last_voice_key_status) {
+                       mas_client_send_voice_key_status_change(pid, g_last_voice_key_status);
+               }
+
                mas_client_activate(pid);
                MAS_LOGD("MA Client with appid %s exists, requesting speech data", (appid ? appid : "NULL"));
                /*
@@ -615,14 +635,15 @@ int mas_ui_client_change_assistant(const char* appid)
        return 0;
 }
 
-int __mas_assistant_info_cb(const char* appid, const char* name, const char* icon_path,
-               const char* wakeup_list[], const char* wakeup_language[], int cnt_wakeup,
-               const char* supported_lang[], int cnt_lang, const char* wakeup_engine,
-               bool custom_ui_option, void* user_data) {
+int __mas_assistant_info_cb(ma_assistant_info_s* info, void* user_data) {
        MAS_LOGD("__mas_assistant_info_cb called");
 
-       if (NULL == appid) {
-               MAS_LOGD("app_id NULL, returning");
+       if (NULL == info) {
+               MAS_LOGE("info NULL, returning");
+               return -1;
+       }
+       if (NULL == info->app_id) {
+               MAS_LOGE("app_id NULL, returning");
                return -1;
        }
 
@@ -638,8 +659,8 @@ int __mas_assistant_info_cb(const char* appid, const char* name, const char* ico
                g_maclient_info[index].used = true;
                g_maclient_info[index].preprocessing_allow_mode = MA_PREPROCESSING_ALLOW_NONE;
                g_maclient_info[index].preprocessing_allow_appid[0] = '\0';
-               MAS_LOGD("app_id(%s)", appid);
-               strncpy(g_maclient_info[index].appid, appid, MAX_APPID_LEN);
+               MAS_LOGD("app_id(%s)", info->app_id);
+               strncpy(g_maclient_info[index].appid, info->app_id, MAX_APPID_LEN);
                g_maclient_info[index].appid[MAX_APPID_LEN - 1] = '\0';
 
                if (is_current_preprocessing_assistant(g_maclient_info[index].appid)) {
@@ -647,12 +668,12 @@ int __mas_assistant_info_cb(const char* appid, const char* name, const char* ico
                }
 
                for (loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
-                       if (loop < cnt_wakeup && wakeup_list[loop]) {
-                               MAS_LOGD("wakeup_list(%d)(%s)(%s)", loop, wakeup_list[loop], wakeup_language[loop]);
-                               strncpy(g_maclient_info[index].wakeup_word[loop], wakeup_list[loop], MAX_WAKEUP_WORD_LEN);
+                       if (loop < info->cnt_wakeup && info->wakeup_list[loop]) {
+                               MAS_LOGD("wakeup_list(%d)(%s)(%s)", loop, info->wakeup_list[loop], info->wakeup_language[loop]);
+                               strncpy(g_maclient_info[index].wakeup_word[loop], info->wakeup_list[loop], MAX_WAKEUP_WORD_LEN);
                                g_maclient_info[index].wakeup_word[loop][MAX_WAKEUP_WORD_LEN - 1] = '\0';
-                               if (wakeup_language[loop]) {
-                                       strncpy(g_maclient_info[index].wakeup_language[loop], wakeup_language[loop], MAX_SUPPORTED_LANGUAGE_LEN);
+                               if (info->wakeup_language[loop]) {
+                                       strncpy(g_maclient_info[index].wakeup_language[loop], info->wakeup_language[loop], MAX_SUPPORTED_LANGUAGE_LEN);
                                        g_maclient_info[index].wakeup_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
                                } else {
                                        strncpy(g_maclient_info[index].wakeup_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
@@ -663,24 +684,29 @@ int __mas_assistant_info_cb(const char* appid, const char* name, const char* ico
                }
 
                for (loop = 0;loop < MAX_SUPPORTED_LANGUAGES_NUM;loop++) {
-                       if (loop < cnt_lang && supported_lang[loop]) {
-                               MAS_LOGD("supported_lang(%d)(%s)", loop, supported_lang[loop]);
-                               strncpy(g_maclient_info[index].supported_language[loop], supported_lang[loop], MAX_SUPPORTED_LANGUAGE_LEN);
+                       if (loop < info->cnt_lang && info->supported_lang[loop]) {
+                               MAS_LOGD("supported_lang(%d)(%s)", loop, info->supported_lang[loop]);
+                               strncpy(g_maclient_info[index].supported_language[loop], info->supported_lang[loop], MAX_SUPPORTED_LANGUAGE_LEN);
                                g_maclient_info[index].supported_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
                        } else {
                                strncpy(g_maclient_info[index].supported_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
                        }
                }
 
-               MAS_LOGD("wakeup_engine(%s)", wakeup_engine);
-               if (wakeup_engine) {
-                       strncpy(g_maclient_info[index].wakeup_engine, wakeup_engine, MAX_APPID_LEN);
+               MAS_LOGD("wakeup_engine(%s)", info->wakeup_engine);
+               if (info->wakeup_engine) {
+                       strncpy(g_maclient_info[index].wakeup_engine, info->wakeup_engine, MAX_APPID_LEN);
                        g_maclient_info[index].wakeup_engine[MAX_APPID_LEN - 1] = '\0';
                } else {
                        g_maclient_info[index].wakeup_engine[0] = '\0';
-                       MAS_LOGW("Wakeup engine information not provided for : %s", appid);
+                       MAS_LOGW("Wakeup engine information not provided for : %s", info->app_id);
                }
-               g_maclient_info[index].custom_ui_option = custom_ui_option;
+               g_maclient_info[index].custom_ui_option = info->custom_ui_option;
+
+               MAS_LOGD("voice_key_support_mode(%d)", info->voice_key_support_mode);
+               g_maclient_info[index].voice_key_support_mode = info->voice_key_support_mode;
+               MAS_LOGD("voice_key_tap_duration(%f)", info->voice_key_tap_duration);
+               g_maclient_info[index].voice_key_tap_duration = info->voice_key_tap_duration;
        } else {
                MAS_LOGD("Couldn't find an empty slot for storing assistant info");
        }
@@ -816,6 +842,7 @@ static int init_wakeup(void)
        process_activated_setting();
 
        mas_prelaunch_default_assistant();
+       mas_update_voice_key_support_mode();
 
        /* For the case of preprocessing assistant, it always have to be launched beforehand */
        char *vconf_str;
@@ -1168,6 +1195,36 @@ int mas_prelaunch_default_assistant()
        return 0;
 }
 
+int mas_update_voice_key_support_mode()
+{
+       /* CHECK NEEDED : should the code segment below and activation logic above be moved to wakeup manger? */
+       bool successful = false;
+       const char *default_assistant = NULL;
+       if (0 == multi_assistant_service_plugin_get_default_assistant(&default_assistant)) {
+               for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+                       if (g_maclient_info[loop].used) {
+                               if (strncmp(default_assistant, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
+                                       float duration = g_maclient_info[loop].voice_key_tap_duration;
+                                       if (0.0f < duration) {
+                                               multi_assistant_service_plugin_set_voice_key_tap_duration(duration);
+                                       } else {
+                                               multi_assistant_service_plugin_unset_voice_key_tap_duration();
+                                       }
+                                       multi_assistant_service_plugin_set_voice_key_support_mode(
+                                               g_maclient_info[loop].voice_key_support_mode);
+                                       successful = true;
+                               }
+                       }
+               }
+       }
+
+       if (!successful) {
+               multi_assistant_service_plugin_unset_voice_key_tap_duration();
+               multi_assistant_service_plugin_set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE_NONE);
+       }
+       return 0;
+}
+
 ma_preprocessing_allow_mode_e get_preprocessing_allow_mode(const char* appid)
 {
        for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
index 6eed1f5..6dedaf4 100644 (file)
@@ -232,6 +232,8 @@ static bool __validate_streaming_event_order(int pid, mas_speech_streaming_event
                {MAS_SPEECH_STREAMING_EVENT_CONTINUE, MAS_SPEECH_STREAMING_EVENT_CONTINUE},
                {MAS_SPEECH_STREAMING_EVENT_CONTINUE, MAS_SPEECH_STREAMING_EVENT_FINISH},
                {MAS_SPEECH_STREAMING_EVENT_FINISH, MAS_SPEECH_STREAMING_EVENT_START},
+               /* If there is no audio data even after the start streaming request */
+               {MAS_SPEECH_STREAMING_EVENT_FINISH, MAS_SPEECH_STREAMING_EVENT_FINISH},
        };
 
        if (pid != previous_pid) {
@@ -340,6 +342,7 @@ static void __error_cb(int error, const char* err_msg, void* user_data)
 static void __setting_changed_cb(void *user_data)
 {
        mas_prelaunch_default_assistant();
+       mas_update_voice_key_support_mode();
        MAS_LOGD( "[SUCCESS] __setting_changed_cb is called");
 }
 
@@ -374,6 +377,17 @@ static void __wakeup_service_state_changed_cb(ma_service_state_e state, void* us
        mas_set_current_service_state(state);
 }
 
+static void __wakeup_service_voice_key_status_changed_cb(ma_voice_key_status_e status, void* user_data)
+{
+       MAS_LOGD( "[SUCCESS] __wakeup_service_voice_key_status_changed_cb is called, state(%d)", status);
+
+       int pid = mas_get_current_client_pid();
+       int ret = mas_client_send_voice_key_status_change(pid, status);
+       if (0 != ret) {
+               MAS_LOGE("[ERROR] Fail to send voice key status changed information, ret(%d)", ret);
+       }
+}
+
 int multi_assistant_service_plugin_initialize(void)
 {
        MAS_LOGD( "[Enter]");
@@ -468,6 +482,15 @@ int multi_assistant_service_plugin_initialize(void)
        _wakeup_manager_interface.set_assistant_language =
                (wakeup_manager_set_assistant_language)dlsym(g_handle,
                MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_LANGUAGE);
+       _wakeup_manager_interface.set_voice_key_tap_duration =
+               (wakeup_manager_set_voice_key_tap_duration)dlsym(g_handle,
+               MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_TAP_DURATION);
+       _wakeup_manager_interface.unset_voice_key_tap_duration =
+               (wakeup_manager_unset_voice_key_tap_duration)dlsym(g_handle,
+               MA_WAKEUP_MANAGER_FUNC_UNSET_VOICE_KEY_TAP_DURATION);
+       _wakeup_manager_interface.set_voice_key_support_mode =
+               (wakeup_manager_set_voice_key_support_mode)dlsym(g_handle,
+               MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_SUPPORT_MODE);
        _wakeup_manager_interface.set_wakeup_event_callback =
                (wakeup_manager_set_wakeup_event_callback)dlsym(g_handle,
                MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK);
@@ -498,6 +521,9 @@ int multi_assistant_service_plugin_initialize(void)
        _wakeup_manager_interface.set_wakeup_service_state_changed_callback =
                (wakeup_manager_set_wakeup_service_state_changed_callback)dlsym(g_handle,
                MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_SERVICE_STATE_CHANGED_CALLBACK);
+       _wakeup_manager_interface.set_voice_key_status_changed_callback =
+               (wakeup_manager_set_voice_key_status_changed_callback)dlsym(g_handle,
+               MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_STATUS_CHANGED_CALLBACK);
 
        int ret = -1;
        if (NULL != g_handle) {
@@ -984,6 +1010,63 @@ int multi_assistant_service_plugin_get_recording_audio_source_type(char** type)
        return ret;
 }
 
+int multi_assistant_service_plugin_set_voice_key_tap_duration(float duration)
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               wakeup_manager_set_voice_key_tap_duration func = _wakeup_manager_interface.set_voice_key_tap_duration;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_TAP_DURATION);
+               } else {
+                       ret = func(duration);
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to set voice key tap duration, ret(%d)", ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+       return ret;
+}
+
+int multi_assistant_service_plugin_unset_voice_key_tap_duration()
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               wakeup_manager_unset_voice_key_tap_duration func = _wakeup_manager_interface.unset_voice_key_tap_duration;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UNSET_VOICE_KEY_TAP_DURATION);
+               } else {
+                       ret = func();
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to unset voice key tap duration, ret(%d)", ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+       return ret;
+}
+
+int multi_assistant_service_plugin_set_voice_key_support_mode(int mode)
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               wakeup_manager_set_voice_key_support_mode func = _wakeup_manager_interface.set_voice_key_support_mode;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_SUPPORT_MODE);
+               } else {
+                       ret = func(mode);
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to set voice key support mode, ret(%d)", ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+       return ret;
+}
+
 int multi_assistant_service_plugin_set_wake_word_audio_require_flag(const char* appid, bool require)
 {
        int ret = -1;
@@ -1084,6 +1167,12 @@ int multi_assistant_service_plugin_set_callbacks(void)
                return ret;
        }
 
+       ret = multi_assistant_service_plugin_set_voice_key_status_changed_callback(__wakeup_service_voice_key_status_changed_cb, NULL);
+       if (0 != ret) {
+               MAS_LOGE("Fail to set wakeup engine command cb");
+               return ret;
+       }
+
        return 0;
 }
 
@@ -1265,3 +1354,20 @@ int multi_assistant_service_plugin_set_wakeup_service_state_changed_callback(wak
        return ret;
 }
 
+int multi_assistant_service_plugin_set_voice_key_status_changed_callback(wakeup_service_voice_key_status_changed_cb callback, void* user_data)
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               wakeup_manager_set_voice_key_status_changed_callback func = _wakeup_manager_interface.set_voice_key_status_changed_callback;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_STATUS_CHANGED_CALLBACK);
+               } else {
+                       ret = func(callback, user_data);
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
+                       }
+               }
+       }
+       return ret;
+}
+