Implement features for adding/removing wake words 10/224210/6
authorJi-hoon Lee <dalton.lee@samsung.com>
Fri, 7 Feb 2020 04:52:35 +0000 (13:52 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Thu, 2 Apr 2020 12:25:59 +0000 (21:25 +0900)
Change-Id: Ida57e6abd6d0c8b28b79efe84803087035a48a45

17 files changed:
CMakeLists.txt
inc/multi_assistant_config.h
inc/multi_assistant_main.h
inc/multi_assistant_service_client.h
inc/multi_assistant_service_plugin.h
plugins/wakeup-manager/inc/wakeup_engine_manager.h
plugins/wakeup-manager/inc/wakeup_manager.h
plugins/wakeup-manager/inc/wakeup_manager_wrapper.h
plugins/wakeup-manager/src/wakeup_engine_manager.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_server.c
src/multi_assistant_dbus_server.h
src/multi_assistant_service.c
src/multi_assistant_service_plugin.c

index 6e4df5c..78e573c 100644 (file)
@@ -18,6 +18,7 @@ pkg_check_modules(pkgs REQUIRED
        capi-appfw-application
        capi-appfw-app-manager
        capi-appfw-package-manager
+       capi-appfw-preference
        capi-appfw-service-application
        capi-media-audio-io
        capi-network-connection
index a5810ac..1cffe06 100644 (file)
@@ -57,6 +57,11 @@ extern "C"
 #define VOICE_KEY_SUPPORT_MODE_STRING_TAP_TO_TALK "tap_to_talk"
 #define VOICE_KEY_SUPPORT_MODE_STRING_ALL "all"
 
+#define MAX_WAKEUP_WORDS_NUM 255
+#define MAX_WAKEUP_WORD_LEN 32
+#define MAX_SUPPORTED_LANGUAGES_NUM 255
+#define MAX_SUPPORTED_LANGUAGE_LEN 16
+
 typedef enum {
        VOICE_KEY_SUPPORT_MODE_NONE,
        VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK,
@@ -81,6 +86,12 @@ typedef struct {
 
 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);
+int mas_config_load_custom_wake_words(const char* app_id,
+       char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+       char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+int mas_config_save_custom_wake_words(const char* app_id,
+       char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+       char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
 
 #ifdef __cplusplus
 }
index 81018ac..32ab00b 100644 (file)
@@ -67,6 +67,8 @@
 #define MA_METHOD_SEND_PREPROCESSING_RESULT                    "ma_method_send_preprocessing_result"
 #define MA_METHOD_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG     "ma_method_set_wake_word_audio_require_flag"
 #define MA_METHOD_SET_ASSISTANT_LANGUAGE                       "ma_method_set_assistant_language"
+#define MA_METHOD_ADD_WAKE_WORD                                                "ma_method_add_wake_word"
+#define MA_METHOD_REMOVE_WAKE_WORD                                     "ma_method_remove_wake_word"
 #define MA_METHOD_ERROR                                                                "ma_method_error"
 
 #define MA_UI_METHOD_INITIALIZE                                                "ma_ui_method_initialize"
index 0c93cf6..82b0424 100644 (file)
@@ -85,6 +85,10 @@ int mas_client_set_assistant_language(int pid, const char* language);
 
 int mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status);
 
+int mas_client_add_wake_word(int pid, const char* wake_word, const char* language);
+
+int mas_client_remove_wake_word(int pid, const char* wake_word, const char* language);
+
 int mas_ui_client_initialize(int pid);
 
 int mas_ui_client_deinitialize(int pid);
index de04670..f7009c2 100644 (file)
@@ -43,6 +43,8 @@ int multi_assistant_service_plugin_set_language(const char* language);
 
 int multi_assistant_service_plugin_add_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
 
+int multi_assistant_service_plugin_remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
+
 int multi_assistant_service_plugin_add_assistant_language(const char* appid, const char* language);
 
 int multi_assistant_service_plugin_set_assistant_wakeup_engine(const char* appid, const char* engine);
@@ -119,6 +121,8 @@ typedef int (*wakeup_manager_deinitialize)(void);
 typedef int (*wakeup_manager_get_settings)(ma_plugin_settings **settings, size_t *struct_size);
 #define MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_WAKEUP_WORD "wakeup_manager_add_assistant_wakeup_word"
 typedef int (*wakeup_manager_add_assistant_wakeup_word)(const char* appid, const char* wakeup_word, const char* language);
+#define MA_WAKEUP_MANAGER_FUNC_REMOVE_ASSISTANT_WAKEUP_WORD "wakeup_manager_remove_assistant_wakeup_word"
+typedef int (*wakeup_manager_remove_assistant_wakeup_word)(const char* appid, const char* wakeup_word, const char* language);
 #define MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE "wakeup_manager_add_assistant_language"
 typedef int (*wakeup_manager_add_assistant_language)(const char* appid, const char* language);
 #define MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_WAKEUP_ENGINE "wakeup_manager_set_assistant_wakeup_engine"
@@ -197,6 +201,7 @@ typedef struct {
        wakeup_manager_deinitialize                                                                     deinitialize;
        wakeup_manager_get_settings                                                                     get_settings;
        wakeup_manager_add_assistant_wakeup_word                                        add_assistant_wakeup_word;
+       wakeup_manager_remove_assistant_wakeup_word                                     remove_assistant_wakeup_word;
        wakeup_manager_add_assistant_language                                           add_assistant_language;
        wakeup_manager_set_assistant_wakeup_engine                                      set_assistant_wakeup_engine;
        wakeup_manager_set_default_assistant                                            set_default_assistant;
index fb668a9..4729dc5 100644 (file)
@@ -50,6 +50,8 @@ typedef int (*wakeup_engine_activate)(void);
 typedef int (*wakeup_engine_deactivate)(void);
 #define MA_WAKEUP_ENGINE_FUNC_ADD_WAKEUP_WORD "wakeup_engine_add_wakeup_word"
 typedef int (*wakeup_engine_add_wakeup_word)(const char* appid, const char* wakeup_word, const char* language);
+#define MA_WAKEUP_ENGINE_FUNC_REMOVE_WAKEUP_WORD "wakeup_engine_remove_wakeup_word"
+typedef int (*wakeup_engine_remove_wakeup_word)(const char* appid, const char* wakeup_word, const char* language);
 #define MA_WAKEUP_ENGINE_FUNC_ADD_LANGUAGE "wakeup_engine_add_language"
 typedef int (*wakeup_engine_add_language)(const char* appid, const char* language);
 #define MA_WAKEUP_ENGINE_FUNC_SET_LANGUAGE "wakeup_engine_set_language"
@@ -99,6 +101,7 @@ typedef struct {
        wakeup_engine_activate                                                                  activate;
        wakeup_engine_deactivate                                                                deactivate;
        wakeup_engine_add_wakeup_word                                                   add_wakeup_word;
+       wakeup_engine_remove_wakeup_word                                                remove_wakeup_word;
        wakeup_engine_add_language                                                              add_language;
        wakeup_engine_set_language                                                              set_language;
        wakeup_engine_update_manager_state                                              update_manager_state;
@@ -170,6 +173,7 @@ public:
 
        void engine_add_target_assistant(string engine_name, string appid);
        void engine_add_wakeup_word(string appid, string wakeup_word, string language);
+       void engine_remove_wakeup_word(string appid, string wakeup_word, string language);
        void engine_set_assistant_specific_command(string appid, string command);
        void engine_set_dependency_module_command(string engine_name, string command);
        void engine_feed_audio_data(long time, void* data, int len);
index 0f2d6ed..8b52f89 100644 (file)
@@ -89,6 +89,7 @@ public:
 
        bool add_assistant_language(string appid, string language);
        bool add_assistant_wakeup_word(string appid, string wakeup_word, string language);
+       bool remove_assistant_wakeup_word(string appid, string wakeup_word, string language);
        bool set_assistant_wakeup_engine(string appid, string engine);
        bool set_assistant_language(string appid, string language);
 
index cdcaa08..45ac567 100644 (file)
@@ -73,6 +73,8 @@ EXPORT_API int wakeup_manager_get_settings(ma_plugin_settings **settings, size_t
 
 EXPORT_API int wakeup_manager_add_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
 
+EXPORT_API int wakeup_manager_remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
+
 EXPORT_API int wakeup_manager_add_assistant_language(const char* appid, const char* language);
 
 EXPORT_API int wakeup_manager_set_assistant_wakeup_engine(const char* appid, const char *engine);
index 642b0f8..1b06f8b 100644 (file)
@@ -569,6 +569,27 @@ void CWakeupEngineManager::engine_add_wakeup_word(string appid, string wakeup_wo
                                        MWR_LOGE("[ERROR] wakeup engine %s threw exception : %s",
                                                info.engine_name.c_str(), e.what());
                                }
+                       } else {
+                               MWR_LOGE("Wakeup Engine does not provide add_wakeup_word");
+                       }
+               }
+       }
+}
+
+void CWakeupEngineManager::engine_remove_wakeup_word(string appid, string wakeup_word, string language)
+{
+       for (const auto& info : mEngineInfo) {
+               bool found = contains(info.assistant_list, appid);
+               if (found) {
+                       if (info.interface.remove_wakeup_word) {
+                               try {
+                                       info.interface.remove_wakeup_word(appid.c_str(), wakeup_word.c_str(), language.c_str());
+                               } catch (const std::exception& e) {
+                                       MWR_LOGE("[ERROR] wakeup engine %s threw exception : %s",
+                                               info.engine_name.c_str(), e.what());
+                               }
+                       } else {
+                               MWR_LOGE("Wakeup Engine does not provide remove_wakeup_word");
                        }
                }
        }
@@ -776,6 +797,9 @@ void CWakeupEngineManager::add_engine(string name, string path)
        info.interface.add_wakeup_word =
                (wakeup_engine_add_wakeup_word)dlsym(info.engine_handle,
                MA_WAKEUP_ENGINE_FUNC_ADD_WAKEUP_WORD);
+       info.interface.remove_wakeup_word =
+               (wakeup_engine_remove_wakeup_word)dlsym(info.engine_handle,
+               MA_WAKEUP_ENGINE_FUNC_REMOVE_WAKEUP_WORD);
        info.interface.add_language =
                (wakeup_engine_add_language)dlsym(info.engine_handle,
                MA_WAKEUP_ENGINE_FUNC_ADD_LANGUAGE);
index ab2b8a4..bce479c 100644 (file)
@@ -259,6 +259,16 @@ bool CWakeupManager::add_assistant_wakeup_word(string appid, string wakeup_word,
        return true;
 }
 
+bool CWakeupManager::remove_assistant_wakeup_word(string appid, string wakeup_word, string language)
+{
+       MWR_LOGD("[ENTER]");
+
+       mWakeupEngineManager.engine_remove_wakeup_word(appid, wakeup_word, language);
+
+       MWR_LOGD("[END]");
+       return true;
+}
+
 bool CWakeupManager::set_assistant_wakeup_engine(string appid, string engine)
 {
        MWR_LOGD("[ENTER]");
index 6e30433..dd51979 100644 (file)
@@ -189,6 +189,23 @@ int wakeup_manager_add_assistant_wakeup_word(const char* appid, const char* wake
        return 0;
 }
 
+int wakeup_manager_remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language)
+{
+       MWR_LOGD("[ENTER]");
+
+       if (NULL == appid || NULL == wakeup_word) {
+               MWR_LOGD("[ERROR] Parameter is invalid, appid(%s), wakeup_word(%s), language(%s)", appid, wakeup_word, language);
+               return -1;
+       }
+
+       if (nullptr == g_wakeup_manager) return -1;
+       g_wakeup_manager->remove_assistant_wakeup_word(
+               string{appid}, string{wakeup_word}, (language ? string{language} : string{}));
+
+       MWR_LOGD("[END]");
+       return 0;
+}
+
 int wakeup_manager_add_assistant_language(const char* appid, const char* language)
 {
        MWR_LOGD("[ENTER]");
index c138d89..056987f 100644 (file)
@@ -237,3 +237,83 @@ int mas_config_get_assistant_info(mas_config_assistant_info_cb callback, void* u
 
        return 0;
 }
+
+int mas_config_load_custom_wake_words(const char* app_id,
+       char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+       char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+       /* Add 1 for additional pipe character */
+       char wakeup_words[MAX_WAKEUP_WORDS_NUM * (MAX_WAKEUP_WORD_LEN + 1)];
+       char wakeup_languages[MAX_WAKEUP_WORDS_NUM * (MAX_SUPPORTED_LANGUAGE_LEN + 1)];
+       memset(wakeup_words, 0x00, sizeof(wakeup_words));
+       memset(wakeup_languages, 0x00, sizeof(wakeup_languages));
+
+       bool existing = false;
+       preference_is_existing("custom_wakeup_words", &existing);
+       if (!existing) return -1;
+       preference_is_existing("custom_wakeup_languages", &existing);
+       if (!existing) return -1;
+
+       char* value = NULL;
+       preference_get_string("custom_wakeup_words", &value);
+       if (NULL == value) return -1;
+       strncpy(wakeup_words, value, sizeof(wakeup_words) - 1);
+       wakeup_words[sizeof(wakeup_words) - 1] = '\0';
+       LOGD("Custom wakeup words loaded : %s", wakeup_words);
+       free(value);
+
+       preference_get_string("custom_wakeup_languages", &value);
+       if (NULL == value) return -1;
+       strncpy(wakeup_languages, value, sizeof(wakeup_languages) - 1);
+       wakeup_languages[sizeof(wakeup_languages) - 1] = '\0';
+       LOGD("Custom wakeup languages loaded : %s", wakeup_languages);
+       free(value);
+
+       char *word_start = wakeup_words;
+       char *language_start = wakeup_languages;
+       char *word_end = NULL;
+       char *language_end = NULL;
+       int index = 0;
+       while (index < MAX_WAKEUP_WORDS_NUM) {
+               word_end = strchrnul(word_start, '|');
+               language_end = strchrnul(language_start, '|');
+               if ('\0' == *word_end || '\0' == *language_end) break;
+               *word_end = '\0';
+               *language_end = '\0';
+               if (0 == strlen(word_start)) break;
+               strncpy(wakeup_word[index], word_start, MAX_WAKEUP_WORD_LEN - 1);
+               strncpy(wakeup_language[index], language_start, MAX_WAKEUP_WORD_LEN - 1);
+               word_start = word_end + 1;
+               language_start = language_end + 1;
+               LOGD("Added custom wakeup word : (%s) (%s)", wakeup_word[index], wakeup_language[index]);
+               index++;
+       }
+
+       return 0;
+}
+
+int mas_config_save_custom_wake_words(const char* app_id,
+       char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+       char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+       /* Add 1 for additional pipe character */
+       char wakeup_words[MAX_WAKEUP_WORDS_NUM * (MAX_WAKEUP_WORD_LEN + 1)];
+       char wakeup_languages[MAX_WAKEUP_WORDS_NUM * (MAX_SUPPORTED_LANGUAGE_LEN + 1)];
+       memset(wakeup_words, 0x00, sizeof(wakeup_words));
+       memset(wakeup_languages, 0x00, sizeof(wakeup_languages));
+       for (int loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+               if (strlen(wakeup_word[loop]) > 0) {
+                       int wakeup_words_len = strlen(wakeup_words);
+                       strncat(wakeup_words, wakeup_word[loop], sizeof(wakeup_words) - wakeup_words_len - 1);
+                       strcat(wakeup_words, "|");
+                       int wakeup_languages_len = strlen(wakeup_languages);
+                       strncat(wakeup_languages, wakeup_language[loop], sizeof(wakeup_languages) - wakeup_languages_len - 1);
+                       strcat(wakeup_languages, "|");
+               }
+       }
+       wakeup_words[sizeof(wakeup_words) - 1] = '\0';
+       wakeup_languages[sizeof(wakeup_languages) - 1] = '\0';
+       preference_set_string("custom_wakeup_words", wakeup_words);
+       preference_set_string("custom_wakeup_languages", wakeup_languages);
+       return 0;
+}
index a7f567c..fde0cde 100644 (file)
@@ -1082,6 +1082,12 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle
                } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_ASSISTANT_LANGUAGE)) {
                        ma_service_dbus_set_assistant_language(g_conn_listener, msg);
 
+               } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_ADD_WAKE_WORD)) {
+                       ma_service_dbus_add_wake_word(g_conn_listener, msg);
+
+               } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_REMOVE_WAKE_WORD)) {
+                       ma_service_dbus_remove_wake_word(g_conn_listener, msg);
+
                } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_INITIALIZE)) {
                        ma_service_ui_dbus_initialize(g_conn_listener, msg);
 
index 136606b..d4a3767 100644 (file)
@@ -694,6 +694,72 @@ int ma_service_dbus_set_assistant_language(DBusConnection* conn, DBusMessage* ms
        return 0;
 }
 
+int ma_service_dbus_add_wake_word(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = 0;
+       char* wake_word;
+       char* language;
+
+       dbus_message_get_args(msg, &err,
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_STRING, &wake_word,
+               DBUS_TYPE_STRING, &language,
+               DBUS_TYPE_INVALID);
+
+       MAS_LOGD("[DEBUG] MAS ADD WAKE WORD");
+
+       if (dbus_error_is_set(&err)) {
+               MAS_LOGE("[IN ERROR] mas add wake word : Get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = -1; //MAS_ERROR_OPERATION_FAILED;
+       } else {
+               MAS_LOGI("[IN] mas add wake word : pid(%d), wake_word(%s) language(%s)", pid, wake_word, language);
+               ret =  mas_client_add_wake_word(pid, wake_word, language);
+       }
+
+       MAS_LOGD("<<<<<");
+       MAS_LOGD("  ");
+
+       return 0;
+}
+
+int ma_service_dbus_remove_wake_word(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = 0;
+       char* wake_word;
+       char* language;
+
+       dbus_message_get_args(msg, &err,
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_STRING, &wake_word,
+               DBUS_TYPE_STRING, &language,
+               DBUS_TYPE_INVALID);
+
+       MAS_LOGD("[DEBUG] MAS REMOVE WAKE WORD");
+
+       if (dbus_error_is_set(&err)) {
+               MAS_LOGE("[IN ERROR] mas remove wake word : Get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = -1; //MAS_ERROR_OPERATION_FAILED;
+       } else {
+               MAS_LOGI("[IN] mas remove wake word : pid(%d), wake_word(%s) language(%s)", pid, wake_word, language);
+               ret =  mas_client_remove_wake_word(pid, wake_word, language);
+       }
+
+       MAS_LOGD("<<<<<");
+       MAS_LOGD("  ");
+
+       return 0;
+}
+
 int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg)
 {
        DBusError err;
index b1a52a8..24d1759 100644 (file)
@@ -57,6 +57,10 @@ int ma_service_dbus_set_wake_word_audio_require_flag(DBusConnection* conn, DBusM
 
 int ma_service_dbus_set_assistant_language(DBusConnection* conn, DBusMessage* msg);
 
+int ma_service_dbus_add_wake_word(DBusConnection* conn, DBusMessage* msg);
+
+int ma_service_dbus_remove_wake_word(DBusConnection* conn, DBusMessage* msg);
+
 int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg);
 
 int ma_service_ui_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg);
index 2ca3a8c..dde11d9 100644 (file)
@@ -45,10 +45,6 @@ static const char *g_current_lang = "en_US";
 #define WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE "db/multi-assistant/prelaunch_mode"
 
 #define MAX_MACLIENT_INFO_NUM 16
-#define MAX_WAKEUP_WORDS_NUM 255
-#define MAX_WAKEUP_WORD_LEN 32
-#define MAX_SUPPORTED_LANGUAGES_NUM 255
-#define MAX_SUPPORTED_LANGUAGE_LEN 16
 typedef struct {
        bool used;
        char appid[MAX_APPID_LEN];
@@ -573,6 +569,96 @@ int mas_client_set_assistant_language(int pid, const char* language)
        return 0;
 }
 
+int mas_client_add_wake_word(int pid, const char* wake_word, const char* language)
+{
+       const char* pid_appid = NULL;
+       char buf[MAX_APPID_LEN] = {'\0',};
+       int ret = aul_app_get_appid_bypid(pid, buf, sizeof(buf));
+       if (AUL_R_OK == ret) {
+               buf[MAX_APPID_LEN - 1] = '\0';
+               pid_appid = buf;
+       }
+
+       for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+               if (g_maclient_info[loop].used &&
+                       0 == strncmp(buf, g_maclient_info[loop].appid, MAX_APPID_LEN)) {
+                       bool found = false;
+                       bool duplicated = false;
+                       for (int innerLoop = 0;false == found && false == duplicated &&
+                               innerLoop < MAX_WAKEUP_WORDS_NUM;innerLoop++) {
+                               if (0 == strncmp(g_maclient_info[loop].wakeup_word[innerLoop], wake_word, MAX_WAKEUP_WORD_LEN) &&
+                                       0 == strncmp(g_maclient_info[loop].wakeup_language[innerLoop], language, MAX_SUPPORTED_LANGUAGE_LEN)) {
+                                       duplicated = true;
+                               }
+                               if (0 == strlen(g_maclient_info[loop].wakeup_word[innerLoop])) {
+                                       strncpy(g_maclient_info[loop].wakeup_word[innerLoop], wake_word, MAX_WAKEUP_WORD_LEN);
+                                       g_maclient_info[loop].wakeup_word[innerLoop][MAX_WAKEUP_WORD_LEN - 1] = '\0';
+                                       strncpy(g_maclient_info[loop].wakeup_language[innerLoop], language, MAX_SUPPORTED_LANGUAGE_LEN);
+                                       g_maclient_info[loop].wakeup_word[innerLoop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+                                       found = true;
+                               }
+                       }
+                       if (found && !duplicated) {
+                               mas_config_save_custom_wake_words(pid_appid,
+                                       g_maclient_info[loop].wakeup_word,
+                                       g_maclient_info[loop].wakeup_language);
+                       } else {
+                               if (duplicated) {
+                                       LOGE("The wakeup word already exists!");
+                               } else {
+                                       LOGE("No empty slot found while trying to add new wake word!");
+                               }
+                               return -1;
+                       }
+               }
+       }
+
+       multi_assistant_service_plugin_add_assistant_wakeup_word(pid_appid, wake_word, language);
+       return 0;
+}
+
+int mas_client_remove_wake_word(int pid, const char* wake_word, const char* language)
+{
+       const char* pid_appid = NULL;
+       char buf[MAX_APPID_LEN] = {'\0',};
+       int ret = aul_app_get_appid_bypid(pid, buf, sizeof(buf));
+       if (AUL_R_OK == ret) {
+               buf[MAX_APPID_LEN - 1] = '\0';
+               pid_appid = buf;
+       }
+
+       for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+               if (g_maclient_info[loop].used &&
+                       0 == strncmp(buf, g_maclient_info[loop].appid, MAX_APPID_LEN)) {
+                       for (int innerLoop = 0;innerLoop < MAX_WAKEUP_WORDS_NUM;innerLoop++) {
+                               if (0 == strncmp(g_maclient_info[loop].wakeup_word[innerLoop], wake_word, MAX_WAKEUP_WORD_LEN) &&
+                                       0 == strncmp(g_maclient_info[loop].wakeup_language[innerLoop], language, MAX_SUPPORTED_LANGUAGE_LEN)) {
+                                       for (int shift = innerLoop;shift < MAX_WAKEUP_WORDS_NUM - 1;shift++) {
+                                               strncpy(g_maclient_info[loop].wakeup_word[shift],
+                                                       g_maclient_info[loop].wakeup_word[shift + 1], MAX_WAKEUP_WORD_LEN);
+                                               g_maclient_info[loop].wakeup_word[shift][MAX_WAKEUP_WORD_LEN - 1] = '\0';
+                                               strncpy(g_maclient_info[loop].wakeup_language[shift],
+                                                       g_maclient_info[loop].wakeup_language[shift + 1], MAX_SUPPORTED_LANGUAGE_LEN);
+                                               g_maclient_info[loop].wakeup_word[shift][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+                                       }
+                                       memset(g_maclient_info[loop].wakeup_word[MAX_WAKEUP_WORDS_NUM - 1],
+                                               0x00, sizeof(g_maclient_info[loop].wakeup_word));
+                                       memset(g_maclient_info[loop].wakeup_language[MAX_WAKEUP_WORDS_NUM - 1],
+                                               0x00, sizeof(g_maclient_info[loop].wakeup_language));
+
+                                       innerLoop--; /* Just in case there are duplicated items */
+                               }
+                       }
+                       mas_config_save_custom_wake_words(pid_appid,
+                                       g_maclient_info[loop].wakeup_word,
+                                       g_maclient_info[loop].wakeup_language);
+               }
+       }
+
+       multi_assistant_service_plugin_remove_assistant_wakeup_word(pid_appid, wake_word, language);
+       return 0;
+}
+
 int mas_ui_client_initialize(int pid)
 {
        MAS_LOGD("[Enter] pid(%d)", pid);
@@ -747,6 +833,8 @@ static int init_plugin(void)
                        int inner_loop;
                        if (g_maclient_info[loop].used &&
                                0 < strlen(g_maclient_info[loop].appid)) {
+                               mas_config_load_custom_wake_words(g_maclient_info[loop].appid,
+                                       g_maclient_info[loop].wakeup_word, g_maclient_info[loop].wakeup_language);
                                if (0 < strlen(g_maclient_info[loop].wakeup_engine)) {
                                        multi_assistant_service_plugin_set_assistant_wakeup_engine(
                                                g_maclient_info[loop].appid,
index 7a73513..afc7ecb 100644 (file)
@@ -416,6 +416,9 @@ int multi_assistant_service_plugin_initialize(void)
        _wakeup_manager_interface.add_assistant_wakeup_word =
                (wakeup_manager_add_assistant_wakeup_word)dlsym(g_handle,
                MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_WAKEUP_WORD);
+       _wakeup_manager_interface.remove_assistant_wakeup_word =
+               (wakeup_manager_remove_assistant_wakeup_word)dlsym(g_handle,
+               MA_WAKEUP_MANAGER_FUNC_REMOVE_ASSISTANT_WAKEUP_WORD);
        _wakeup_manager_interface.add_assistant_language =
                (wakeup_manager_add_assistant_language)dlsym(g_handle,
                MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE);
@@ -636,7 +639,26 @@ int multi_assistant_service_plugin_add_assistant_wakeup_word(const char* appid,
                } else {
                        ret = func(appid, wakeup_word, language);
                        if (0 != ret) {
-                               MAS_LOGE("[ERROR] Fail to set wakeup word(%s)(%s)(%s), ret(%d)", appid, wakeup_word, language, ret);
+                               MAS_LOGE("[ERROR] Fail to add wakeup word(%s)(%s)(%s), ret(%d)", appid, wakeup_word, language, ret);
+                       }
+               }
+       } else {
+               MAS_LOGE("[ERROR] g_handle is not valid");
+       }
+       return ret;
+}
+
+int multi_assistant_service_plugin_remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language)
+{
+       int ret = -1;
+       if (NULL != g_handle) {
+               wakeup_manager_remove_assistant_wakeup_word func = _wakeup_manager_interface.remove_assistant_wakeup_word;
+               if (NULL == func) {
+                       MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_REMOVE_ASSISTANT_WAKEUP_WORD);
+               } else {
+                       ret = func(appid, wakeup_word, language);
+                       if (0 != ret) {
+                               MAS_LOGE("[ERROR] Fail to remove wakeup word(%s)(%s)(%s), ret(%d)", appid, wakeup_word, language, ret);
                        }
                }
        } else {