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
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+IF(NOT "${TEST_TYPE}" STREQUAL "none")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_TYPE=${TEST_TYPE}")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTEST_TYPE=${TEST_TYPE}")
+ENDIF()
+
# OPTION DEBUG -----------------------------------------------------------------------------------
IF("${_SDEBUG}" MATCHES "debug")
MESSAGE("Building in debug mode.")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
SET(SRCS
- src/multi_assistant_config.c
- src/multi_assistant_service.c
- src/multi_assistant_service_plugin.c
- src/multi_assistant_dbus.c
- src/multi_assistant_dbus_server.c
+ src/service_config.cpp
+ src/application_manager_aul.cpp
+ src/preference_manager_vconf.cpp
+ src/client_manager.cpp
+ src/service_main.cpp
+ src/service_plugin.cpp
+ src/service_ipc_dbus.cpp
+ src/service_ipc_dbus_dispatcher.cpp
+ src/main.cpp
)
ADD_EXECUTABLE(${BINNAME} ${SRCS})
TARGET_LINK_LIBRARIES(${BINNAME} -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS})
ADD_SUBDIRECTORY(plugins)
+
+IF(NOT "${TEST_TYPE}" STREQUAL "none")
+ENABLE_TESTING()
+ADD_SUBDIRECTORY(tests)
+ENDIF()
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __APPLICATION_MANAGER_H__
+#define __APPLICATION_MANAGER_H__
+
+#include <boost/optional.hpp>
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class IApplicationManager {
+public:
+ virtual bool is_application_running(int pid) = 0;
+ virtual bool is_application_running(const std::string& appid) = 0;
+ virtual bool bring_app_to_foreground(const std::string& appid) = 0;
+ virtual bool launch_app_async(const std::string& appid, bool background) = 0;
+ virtual boost::optional<std::string> get_appid_by_pid(int pid) = 0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPLICATION_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __APPLICATION_MANAGER_AUL_H__
+#define __APPLICATION_MANAGER_AUL_H__
+
+#include "application_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class CApplicationManagerAul : public IApplicationManager {
+public:
+ CApplicationManagerAul();
+ ~CApplicationManagerAul();
+
+ virtual bool is_application_running(int pid) override;
+ virtual bool is_application_running(const std::string& appid) override;
+ virtual bool bring_app_to_foreground(const std::string& appid) override;
+ virtual bool launch_app_async(const std::string& appid, bool background) override;
+ virtual boost::optional<std::string> get_appid_by_pid(int pid) override;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPLICATION_MANAGER_AUL_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __CLIENT_MANAGER_H__
+#define __CLIENT_MANAGER_H__
+
+#include "application_manager.h"
+
+#include <string>
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int pid;
+ std::string appid;
+} ma_client_s;
+
+class CClientManager {
+public:
+ CClientManager() {}
+ virtual ~CClientManager() {}
+
+ int set_application_manager(IApplicationManager* manager);
+ int create_client(int pid, std::string appid);
+ int destroy_client_by_pid(int pid);
+ int destroy_client_by_appid(std::string appid);
+
+ int get_client_num();
+ int find_client_pid_by_index(unsigned int index);
+
+ int find_client_pid_by_appid(std::string appid);
+ std::string find_client_appid_by_pid(int pid);
+
+ bool check_client_validity_by_appid(std::string appid);
+private:
+ ma_client_s* find_client_by_appid(std::string appid);
+ ma_client_s* find_client_by_pid(int pid);
+ ma_client_s* get_client_by_index(unsigned int index);
+ int destroy_client(ma_client_s* client);
+
+private:
+ IApplicationManager* mApplicationManager{nullptr};
+ GSList* mClientList{nullptr};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLIENT_MANAGER_H__ */
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __MULTI_ASSISTANT_CONFIG_H__
-#define __MULTI_ASSISTANT_CONFIG_H__
-
-#include <tizen.h>
-#include <tzplatform_config.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define MAX_WAKEUP_LIST_NUM 32
-#define MAX_SUPPORTED_LANGUAGE_NUM 128
-
-/**************************************************************************************
- *** Definitions for xml file
- *************************************************************************************/
-#define MA_TAG_ASSISTANT_BASE "multi-assistant"
-#define MA_TAG_ASSISTANT_NAME "name"
-#define MA_TAG_ASSISTANT_APPID "appid"
-#define MA_TAG_ASSISTANT_ICON_PATH "icon-path"
-#define MA_TAG_ASSISTANT_LANGUAGE_SET "languages"
-#define MA_TAG_ASSISTANT_LANGUAGE "language"
-#define MA_TAG_ASSISTANT_WAKEUP_WORD_SET "wakeup-words"
-#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
- *************************************************************************************/
-#define MA_RETRY_COUNT 5
-
-#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;
- const char* icon_path;
- const char* wakeup_list[MAX_WAKEUP_LIST_NUM];
- const char* wakeup_language[MAX_WAKEUP_LIST_NUM];
- int cnt_wakeup;
- const char* supported_lang[MAX_SUPPORTED_LANGUAGE_NUM];
- 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)(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
-}
-#endif
-
-/**
- * @}
- */
-
-#endif /* __MULTI_ASSISTANT_CONFIG_H__ */
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef _MULTI_ASSISTANT_SERVICE_H_
-#define _MULTI_ASSISTANT_SERVICE_H_
-
-#include <dlog/dlog.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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);
-
-int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type);
-
-int mas_client_get_audio_source_type(int pid, char** type);
-
-int mas_client_request_speech_data(int pid);
-
-int mas_client_send_asr_result(int pid, int event, char* asr_result);
-
-int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json);
-
-int mas_client_send_recognition_result(int pid, int result);
-
-int mas_client_start_streaming_audio_data(int pid, int type);
-
-int mas_client_stop_streaming_audio_data(int pid, int type);
-
-int mas_client_update_voice_feedback_state(int pid, int state);
-
-int mas_client_set_assistant_specific_command(int pid, const char *command);
-
-int mas_client_set_background_volume(int pid, double ratio);
-
-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);
-
-int mas_ui_client_change_assistant(const char* appid);
-
-int mas_get_current_client_pid();
-
-int mas_get_current_preprocessing_client_pid();
-
-int mas_get_client_pid_by_wakeup_word(const char *wakeup_word);
-
-int mas_get_client_pid_by_appid(const char *appid);
-
-const char* mas_get_client_appid_by_pid(int pid);
-
-bool mas_get_client_custom_ui_option_by_appid(const char *appid);
-
-const char* mas_get_client_appid_by_wakeup_word(const char *wakeup_word);
-
-int mas_set_current_client_by_wakeup_word(const char *wakeup_word);
-
-int mas_set_current_client_by_appid(const char *appid);
-
-int mas_launch_client_by_wakeup_word(const char *wakeup_word);
-
-int mas_prelaunch_default_assistant();
-
-int mas_set_current_service_state(ma_service_state_e state);
-
-ma_service_state_e mas_get_current_service_state();
-
-int mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode);
-
-int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event);
-
-int mas_update_voice_key_support_mode();
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MULTI_ASSISTANT_SERVICE_H_ */
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef _MULTI_WAKEUP_RECOGNIZER_H_
-#define _MULTI_WAKEUP_RECOGNIZER_H_
-
-#include <dlog/dlog.h>
-
-#include <multi_assistant_common.h>
-#include <multi_assistant_service.h>
-#include <multi_assistant_internal.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*wakeup_service_wakeup_event_cb)(mas_wakeup_event_info wakeup_info, const char* wakeup_word, void* user_data);
-
-typedef void (*wakeup_service_speech_streaming_cb)(mas_speech_streaming_event_e event, unsigned char* buffer, int len, void *user_data);
-
-typedef void (*wakeup_service_speech_status_cb)(mas_speech_status_e status, void *user_data);
-
-typedef void (*wakeup_service_setting_changed_cb)(void *user_data);
-
-typedef void (*wakeup_service_error_cb)(int error, const char* err_msg, void* user_data);
-
-typedef void (*wakeup_service_streaming_section_changed_cb)(ma_audio_streaming_data_section_e section, void* user_data);
-
-typedef void (*wakeup_service_wakeup_engine_command_cb)(mas_wakeup_engine_command_target_e target, const char* assistant_name, const char* command, void* user_data);
-
-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
-
-#endif /* _MULTI_WAKEUP_RECOGNIZER_H_ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __PREFERENCE_MANAGER_H__
+#define __PREFERENCE_MANAGER_H__
+
+#include <string>
+#include <boost/optional.hpp>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*preference_changed_cb)(std::string key, void* user_data);
+
+class IPreferenceManager {
+public:
+ virtual boost::optional<std::string> get_string(const std::string& key) = 0;
+ virtual boost::optional<int> get_int(const std::string& key) = 0;
+ virtual boost::optional<bool> get_bool(const std::string& key) = 0;
+
+ virtual bool register_changed_callback(
+ const std::string& key, preference_changed_cb calback, void* user_data) = 0;
+ virtual bool unregister_changed_callback(
+ const std::string& key, preference_changed_cb callback) = 0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PREFERENCE_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __PREFERENCE_MANAGER_VCONF_H__
+#define __PREFERENCE_MANAGER_VCONF_H__
+
+#include "preference_manager.h"
+
+#include <map>
+#include <list>
+#include <tuple>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef std::tuple<preference_changed_cb, void*> CallbackEntry;
+
+class CPreferenceManagerVconf : public IPreferenceManager {
+public:
+ CPreferenceManagerVconf();
+ ~CPreferenceManagerVconf();
+
+ boost::optional<std::string> get_string(const std::string& key) override;
+ boost::optional<int> get_int(const std::string& key) override;
+ boost::optional<bool> get_bool(const std::string& key) override;
+
+ bool register_changed_callback(
+ const std::string& key, preference_changed_cb calback, void* user_data) override;
+ bool unregister_changed_callback(
+ const std::string& key, preference_changed_cb callback) override;
+
+ const std::map<std::string, std::list<CallbackEntry>>& get_callbacks() {
+ return mCallbackEntries;
+ }
+
+private:
+ std::map<std::string, std::list<CallbackEntry>> mCallbackEntries;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PREFERENCE_MANAGER_VCONF_H__ */
-#ifndef __MULTI_ASSISTANT_SERVICE_H__
-#define __MULTI_ASSISTANT_SERVICE_H__
+#ifndef __SERVICE_COMMON_H__
+#define __SERVICE_COMMON_H__
#include <app.h>
#include <glib.h>
-#include "multi_wakeup_recognizer.h"
+#include <dlog/dlog.h>
+#include <multi_assistant_common.h>
+#include <multi_assistant_service.h>
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "multi-assistant"
+#ifdef TEST_TYPE
+#define conditional_public public
+#else
+#define conditional_public private
+#endif
+
#define MAS_SECURE_LOG_(id, prio, tag, fmt, arg...) \
({ do { \
__dlog_print(id, prio, tag, "%s: %s(%d) > [SECURE_LOG] " fmt, __MODULE__, __func__, __LINE__, ##arg); \
/**************************************************************************************
*** Definitions for DBus
*************************************************************************************/
-#define MA_CLIENT_SERVICE_NAME "org.tizen.multiassistant.maclient"
-#define MA_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maclient"
-#define MA_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.maclient"
+#define MA_CLIENT_SERVICE_NAME "org.tizen.multiassistant.maclient"
+#define MA_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maclient"
+#define MA_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.maclient"
-#define MA_UI_CLIENT_SERVICE_NAME "org.tizen.multiassistant.mauiclient"
-#define MA_UI_CLIENT_SERVICE_OBJECT_PATH"/org/tizen/multiassistant/mauiclient"
-#define MA_UI_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.mauiclient"
+#define MA_UI_CLIENT_SERVICE_NAME "org.tizen.multiassistant.mauiclient"
+#define MA_UI_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/mauiclient"
+#define MA_UI_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.mauiclient"
-#define MA_SERVER_SERVICE_NAME "org.tizen.multiassistant.maserver"
-#define MA_SERVER_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maserver"
-#define MA_SERVER_SERVICE_INTERFACE "org.tizen.multiassistant.maserver"
+#define MA_SERVER_SERVICE_NAME "org.tizen.multiassistant.maserver"
+#define MA_SERVER_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maserver"
+#define MA_SERVER_SERVICE_INTERFACE "org.tizen.multiassistant.maserver"
/**************************************************************************************
*** Definitions for DBus methods
#define MA_METHOD_SET_PREPROCESSING_ALLOW_MODE "ma_method_set_preprocessing_allow_mode"
#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_WAKEUP_LANGUAGE "ma_method_set_assistant_wakeup_language"
+#define MA_METHOD_SET_ASSISTANT_WAKEUP_LANGUAGE "ma_method_set_assistant_wakeup_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"
#define MAS_UI_METHOD_SEND_RECOGNITION_RESULT "mas_ui_method_send_recognition_result"
#define MAS_UI_METHOD_ENABLE_COMMON_UI "mas_ui_method_enable_common_ui"
-#endif /* __MULTI_ASSISTANT_SERVICE_H__ */
+typedef void (*wakeup_service_wakeup_event_cb)(mas_wakeup_event_info wakeup_info, void* user_data);
+
+typedef void (*wakeup_service_speech_streaming_cb)(mas_speech_streaming_event_e event, void* buffer, int len, void *user_data);
+
+typedef void (*wakeup_service_speech_status_cb)(mas_speech_status_e status, void *user_data);
+
+typedef void (*wakeup_service_setting_changed_cb)(void *user_data);
+
+typedef void (*wakeup_service_error_cb)(int error, const char* err_msg, void* user_data);
+
+typedef void (*wakeup_service_streaming_section_changed_cb)(ma_audio_streaming_data_section_e section, void* user_data);
+
+typedef void (*wakeup_service_wakeup_engine_command_cb)(mas_wakeup_engine_command_target_e target, const char* assistant_name, const char* command, void* user_data);
+
+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);
+
+#define MAX_WAKEUP_WORDS_NUM 255
+#define MAX_WAKEUP_WORD_LEN 32
+#define MAX_SUPPORTED_LANGUAGES_NUM 255
+#define MAX_SUPPORTED_LANGUAGE_LEN 16
+
+#define MAX_APPID_LEN 255
+
+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;
+
+#endif /* __SERVICE_COMMON_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SERVICE_CONFIG_H__
+#define __SERVICE_CONFIG_H__
+
+#include <tizen.h>
+#include <tzplatform_config.h>
+
+#include "service_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**************************************************************************************
+ *** Definitions for xml file
+ *************************************************************************************/
+#define MA_TAG_ASSISTANT_BASE "multi-assistant"
+#define MA_TAG_ASSISTANT_NAME "name"
+#define MA_TAG_ASSISTANT_APPID "appid"
+#define MA_TAG_ASSISTANT_ICON_PATH "icon-path"
+#define MA_TAG_ASSISTANT_LANGUAGE_SET "languages"
+#define MA_TAG_ASSISTANT_LANGUAGE "language"
+#define MA_TAG_ASSISTANT_WAKEUP_WORD_SET "wakeup-words"
+#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
+ *************************************************************************************/
+#define MA_RETRY_COUNT 5
+
+#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 struct ma_assistant_info_s {
+ ma_assistant_info_s() :
+ app_id{nullptr},
+ name{nullptr},
+ icon_path{nullptr},
+ wakeup_list{0x00, },
+ wakeup_language{0x00, },
+ cnt_wakeup{0},
+ supported_lang{0x00, },
+ cnt_lang{0},
+ wakeup_engine{nullptr},
+ custom_ui_option{false},
+ /* TODO: Define these two default values somewhere else */
+ voice_key_support_mode{VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK},
+ voice_key_tap_duration{0.0f} /* Meaning not set */
+ {}
+
+ const char* app_id;
+ const char* name;
+ const char* icon_path;
+ const char* wakeup_list[MAX_WAKEUP_WORDS_NUM];
+ const char* wakeup_language[MAX_WAKEUP_WORDS_NUM];
+ int cnt_wakeup;
+ const char* supported_lang[MAX_SUPPORTED_LANGUAGES_NUM];
+ 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 (*service_config_assistant_info_cb)(ma_assistant_info_s* info, void* user_data);
+
+class CServiceConfig {
+public:
+ CServiceConfig() {};
+ virtual ~CServiceConfig() {};
+
+ int get_assistant_info(service_config_assistant_info_cb callback, void* user_data);
+
+ int add_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+ int remove_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+ int load_custom_wake_words(const char* app_id,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+ int save_custom_wake_words(const char* app_id,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+ int get_custom_wake_word_num(
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+ bool has_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN]);
+private:
+ int parse_assistant_info(service_config_assistant_info_cb callback,
+ const char *path, void* user_data);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __SERVICE_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SERVICE_IPC_DBUS_H__
+#define __SERVICE_IPC_DBUS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dbus/dbus.h>
+#include <Ecore.h>
+
+#include "service_ipc_dbus_dispatcher.h"
+
+class CServiceMain;
+
+class CServiceIpcDbus {
+public:
+ CServiceIpcDbus() {}
+ virtual ~CServiceIpcDbus() {}
+
+ int open_connection();
+ int close_connection();
+ int send_hello(int pid);
+ int send_error_message(int reason, const char* err_msg);
+ int send_streaming_audio_data(int pid, int event, void* data, unsigned int data_size);
+ int change_active_state(int pid, int state);
+ int send_preprocessing_information(int pid, const char* app_id);
+ int send_streaming_section_changed(int pid, int section);
+ int send_preprocessing_result(int pid, bool result);
+ int send_wakeup_engine_command(int pid, const char* command);
+ int change_service_state(int pid, int state);
+ int change_voice_key_status(int pid, int status);
+ int masc_ui_dbus_send_hello(void);
+ int masc_ui_dbus_send_asr_result(int pid, int event, const char* asr_result);
+ int masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json);
+ int masc_ui_dbus_change_assistant(const char* app_id);
+ int masc_ui_dbus_send_error_message(int reason, const char* err_msg);
+ int masc_ui_dbus_send_recognition_result(int pid, int result);
+ int masc_ui_dbus_enable_common_ui(int enable);
+
+ DBusConnection* get_connection_listener() { return mConnectionListener; }
+ CServiceIpcDbusDispatcher* get_dispatcher() { return &mDispatcher; }
+
+ void set_client_manager(CClientManager* manager) {
+ mClientManager = manager;
+ }
+ void set_service_ipc_observer(IServiceIpcObserver* observer) {
+ mDispatcher.set_ipc_observer(observer);
+ }
+private:
+ int __dbus_check();
+ void connection_free();
+ int reconnect();
+ int mas_check_dbus_connection();
+
+private:
+ CServiceIpcDbusDispatcher mDispatcher;
+
+ DBusConnection* mConnectionSender{NULL};
+ DBusConnection* mConnectionListener{NULL};
+
+ Ecore_Fd_Handler* mFdHandler{NULL};
+
+ int mStreamingDataSerial{0};
+
+ CClientManager* mClientManager{nullptr};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SERVICE_IPC_DBUS_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SERVICE_IPC_DBUS_DISPATCHER_H__
+#define __SERVICE_IPC_DBUS_DISPATCHER_H__
+
+#include <string>
+
+#include <dbus/dbus.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class CServiceMain;
+
+class IServiceIpcObserver {
+public:
+ virtual int on_initialize(int pid) = 0;
+ virtual int on_deinitialize(int pid) = 0;
+ virtual int on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) = 0;
+ virtual int on_get_audio_source_type(int pid, std::string& type) = 0;
+ virtual int on_send_asr_result(int pid, int event, std::string asr_result) = 0;
+ virtual int on_send_result(int pid,
+ std::string display_text, std::string utterance_text, std::string result_json) = 0;
+ virtual int on_send_recognition_result(int pid, int result) = 0;
+ virtual int on_start_streaming_audio_data(int pid, int type) = 0;
+ virtual int on_stop_streaming_audio_data(int pid, int type) = 0;
+ virtual int on_update_voice_feedback_state(int pid, int state) = 0;
+ virtual int on_send_assistant_specific_command(int pid, std::string command) = 0;
+ virtual int on_set_background_volume(int pid, double ratio) = 0;
+ virtual int on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) = 0;
+ virtual int on_send_preprocessing_result(int pid, int result) = 0;
+ virtual int on_set_wake_word_audio_require_flag(int pid, int require) = 0;
+ virtual int on_set_assistant_language(int pid, std::string language) = 0;
+ virtual int on_add_wake_word(int pid, std::string wake_word, std::string language) = 0;
+ virtual int on_remove_wake_word(int pid, std::string wake_word, std::string language) = 0;
+
+ virtual int on_ui_initialize(int pid) = 0;
+ virtual int on_ui_deinitialize(int pid) = 0;
+ virtual int on_ui_change_assistant(std::string app_id) = 0;
+};
+
+class CServiceIpcDbusDispatcher {
+public:
+ CServiceIpcDbusDispatcher() {}
+ virtual ~CServiceIpcDbusDispatcher() {}
+
+ int on_hello(DBusConnection* conn, DBusMessage* msg);
+ int on_initialize(DBusConnection* conn, DBusMessage* msg);
+ int on_deinitialize(DBusConnection* conn, DBusMessage* msg);
+ int on_get_audio_format(DBusConnection* conn, DBusMessage* msg);
+ int on_get_audio_source_type(DBusConnection* conn, DBusMessage* msg);
+ int on_send_asr_result(DBusConnection* conn, DBusMessage* msg);
+ int on_send_result(DBusConnection* conn, DBusMessage* msg);
+ int on_send_recognition_result(DBusConnection* conn, DBusMessage* msg);
+ int on_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg);
+ int on_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg);
+ int on_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg);
+ int on_send_assistant_specific_command(DBusConnection* conn, DBusMessage* msg);
+ int on_set_background_volume(DBusConnection* conn, DBusMessage* msg);
+ int on_set_preprocessing_allow_mode(DBusConnection* conn, DBusMessage* msg);
+ int on_send_preprocessing_result(DBusConnection* conn, DBusMessage* msg);
+ int on_set_wake_word_audio_require_flag(DBusConnection* conn, DBusMessage* msg);
+ int on_set_assistant_language(DBusConnection* conn, DBusMessage* msg);
+ int on_add_wake_word(DBusConnection* conn, DBusMessage* msg);
+ int on_remove_wake_word(DBusConnection* conn, DBusMessage* msg);
+ int on_ui_initialize(DBusConnection* conn, DBusMessage* msg);
+ int on_ui_deinitialize(DBusConnection* conn, DBusMessage* msg);
+ int on_ui_change_assistant(DBusConnection* conn, DBusMessage* msg);
+
+ void set_ipc_observer(IServiceIpcObserver* observer) { mIpcObserver = observer; }
+private:
+ IServiceIpcObserver *mIpcObserver{nullptr};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __SERVICE_IPC_DBUS_DISPATCHER_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SERVICE_MAIN_H__
+#define __SERVICE_MAIN_H__
+
+#include <string>
+
+#include <dlog/dlog.h>
+#include <multi_assistant.h>
+#include <multi_assistant_internal.h>
+#include <package_manager.h>
+
+#include "service_common.h"
+#include "service_config.h"
+#include "client_manager.h"
+#include "service_plugin.h"
+#include "service_ipc_dbus.h"
+#include "application_manager.h"
+#include "preference_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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;
+
+#define ENABLE_MULTI_ASSISTANT_BY_DEFAULT
+
+#define MULTI_ASSISTANT_SETTINGS_ACTIVATED "db/multi-assistant/activated"
+#define WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID "db/multi-assistant/preprocessing_assistant_appid"
+#define WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE "db/multi-assistant/prelaunch_mode"
+
+#define MAX_MACLIENT_INFO_NUM 16
+
+class CServiceMain : public IServiceIpcObserver {
+public:
+ CServiceMain(IApplicationManager& applicationManager, IPreferenceManager& preferenceManager) :
+ mApplicationManager{applicationManager},
+ mPreferenceManager{preferenceManager}
+ {}
+ virtual ~CServiceMain() {}
+
+ int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type);
+ int mas_client_get_audio_source_type(int pid, char** type);
+ int mas_client_send_preprocessing_information(int pid);
+ int mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status);
+ int mas_client_request_speech_data(int pid);
+ int mas_client_send_asr_result(int pid, int event, const char* asr_result);
+ int mas_client_send_result(int pid, const char* display_text,
+ const char* utterance_text, const char* result_json);
+ int mas_client_send_recognition_result(int pid, int result);
+ int mas_client_start_streaming_audio_data(int pid, int type);
+ int mas_client_stop_streaming_audio_data(int pid, int type);
+ int mas_client_update_voice_feedback_state(int pid, int state);
+ int mas_client_set_assistant_specific_command(int pid, const char *command);
+ int mas_client_set_background_volume(int pid, double ratio);
+ int mas_client_set_preprocessing_allow_mode(int pid, ma_preprocessing_allow_mode_e mode, const char* appid);
+ int mas_client_send_preprocessing_result(int pid, bool result);
+ int mas_client_set_wake_word_audio_require_flag(int pid, bool require);
+ int mas_client_set_assistant_language(int pid, const char* language);
+ 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);
+ int mas_ui_client_change_assistant(const char* appid);
+ int mas_get_current_client_pid();
+ int mas_get_current_preprocessing_client_pid();
+ int mas_get_client_pid_by_wakeup_word(const char *wakeup_word);
+ int mas_get_client_pid_by_appid(const char *appid);
+ std::string mas_get_client_appid_by_pid(int pid);
+ bool mas_get_client_custom_ui_option_by_appid(const char *appid);
+ const char* mas_get_client_appid_by_wakeup_word(const char *wakeup_word);
+ int mas_set_current_client_by_wakeup_word(const char *wakeup_word);
+ int mas_set_current_client_by_appid(const char *appid);
+ int mas_launch_client_by_wakeup_word(const char *wakeup_word);
+ int mas_prelaunch_default_assistant();
+ int mas_set_current_service_state(ma_service_state_e state);
+ int mas_bring_client_to_foreground(const char* appid);
+ ma_service_state_e mas_get_current_service_state();
+ int mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode);
+ int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event);
+ int mas_update_voice_key_support_mode();
+
+ virtual int on_initialize(int pid) override;
+ virtual int on_deinitialize(int pid) override;
+ virtual int on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) override;
+ virtual int on_get_audio_source_type(int pid, std::string& type) override;
+ virtual int on_send_asr_result(int pid, int event, std::string asr_result) override;
+ virtual int on_send_result(int pid, std::string display_text,
+ std::string utterance_text, std::string result_json) override;
+ virtual int on_send_recognition_result(int pid, int result) override;
+ virtual int on_start_streaming_audio_data(int pid, int type) override;
+ virtual int on_stop_streaming_audio_data(int pid, int type) override;
+ virtual int on_update_voice_feedback_state(int pid, int state) override;
+ virtual int on_send_assistant_specific_command(int pid, std::string command) override;
+ virtual int on_set_background_volume(int pid, double ratio) override;
+ virtual int on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) override;
+ virtual int on_send_preprocessing_result(int pid, int result) override;
+ virtual int on_set_wake_word_audio_require_flag(int pid, int require) override;
+ virtual int on_set_assistant_language(int pid, std::string language) override;
+ virtual int on_add_wake_word(int pid, std::string wake_word, std::string language) override;
+ virtual int on_remove_wake_word(int pid, std::string wake_word, std::string language) override;
+
+ virtual int on_ui_initialize(int pid) override;
+ virtual int on_ui_deinitialize(int pid) override;
+ virtual int on_ui_change_assistant(std::string app_id) override;
+
+ bool app_create(void *data);
+ void app_terminate(void *data);
+
+ int initialize_service_plugin(void);
+ int deinitialize_service_plugin(void);
+
+ bool is_valid_wakeup_engine(const char* appid);
+ int process_activated_setting();
+
+ int add_assistant_info(ma_assistant_info_s* info);
+
+ CServicePlugin* get_service_plugin() { return &mServicePlugin; }
+private:
+ bool check_preprocessing_assistant_exists();
+ ma_preprocessing_allow_mode_e get_preprocessing_allow_mode(const char* appid);
+ bool is_current_preprocessing_assistant(const char* appid);
+
+private:
+ std::string mCurrentLanguage{"en_US"};
+
+ typedef struct {
+ bool used;
+ char appid[MAX_APPID_LEN];
+ char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN];
+ char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
+ 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];
+ } ma_client_info;
+
+ ma_client_info mClientInfo[MAX_MACLIENT_INFO_NUM];
+
+ int mCurrentClientInfo{0};
+ int mCurrentPreprocessingClientInfo{-1};
+ std::string mWakeupClientAppId;
+ package_manager_h mPackageManagerHandle{NULL};
+
+ PREPROCESSING_STATE mCurrentPreprocessingState{PREPROCESSING_STATE_NONE};
+ ma_service_state_e mCurrentServiceState{MA_SERVICE_STATE_INACTIVE};
+
+ CServiceConfig mServiceConfig;
+ CServicePlugin mServicePlugin;
+ CServiceIpcDbus mServiceIpc;
+
+ ma_voice_key_status_e mLastVoiceKeyStatus{MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH};
+
+ CClientManager mClientManager;
+
+ IApplicationManager& mApplicationManager;
+ IPreferenceManager& mPreferenceManager;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SERVICE_MAIN_H__ */
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SERVICE_PLUGIN_H__
+#define __SERVICE_PLUGIN_H__
+
+#include <tzplatform_config.h>
+
+#include "service_common.h"
+#include "service_ipc_dbus.h"
+#include "service_plugin_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+class CServiceMain;
+
+class CServicePlugin {
+public:
+ CServicePlugin() {};
+ virtual ~CServicePlugin() {};
+
+ int initialize(void);
+ int deinitialize(void);
+ int get_settings(ma_plugin_settings **settings, size_t *struct_size);
+ int set_language(const char* language);
+ int add_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
+ int remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language);
+ int add_assistant_language(const char* appid, const char* language);
+ int set_assistant_wakeup_engine(const char* appid, const char* engine);
+ int set_default_assistant(const char* appid);
+ int get_default_assistant(const char** appid);
+ int activate(void);
+ int deactivate(void);
+ int update_voice_feedback_state(const char* appid, int state);
+ int set_assistant_specific_command(const char *appid, const char* command);
+ int set_background_volume(const char *appid, double ratio);
+ int update_recognition_result(const char* appid, int result);
+ int set_preprocessing_allow_mode(const char* appid, int mode, const char* preprocessing_appid);
+ int process_event(int event, void* data, int len);
+ int start_streaming_utterance_data(void);
+ int stop_streaming_utterance_data(void);
+ int start_streaming_previous_utterance_data(void);
+ int stop_streaming_previous_utterance_data(void);
+ int start_streaming_follow_up_data(void);
+ int stop_streaming_follow_up_data(void);
+ int get_recording_audio_format(int* rate, int* channel, int* audio_type);
+ int get_recording_audio_source_type(char **type);
+ int set_wake_word_audio_require_flag(const char* appid, bool require);
+ int set_assistant_language(const char* appid, const char* language);
+ int set_voice_key_support_mode(int mode);
+ int set_voice_key_tap_duration(float duration);
+ int unset_voice_key_tap_duration(void);
+ int set_callbacks(void);
+ int set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data);
+ int set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
+ int set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
+ int set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
+ int set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data);
+ int set_setting_changed_callback(wakeup_service_setting_changed_cb callback, void* user_data);
+ int set_error_callback(wakeup_service_error_cb callback, void* user_data);
+ int set_streaming_section_changed_callback(wakeup_service_streaming_section_changed_cb callback, void* user_data);
+ int set_wakeup_engine_command_callback(wakeup_service_wakeup_engine_command_cb callback, void* user_data);
+ int set_wakeup_service_state_changed_callback(wakeup_service_wakeup_service_state_changed_cb callback, void* user_data);
+ int set_voice_key_status_changed_callback(wakeup_service_voice_key_status_changed_cb callback, void* user_data);
+
+ bool is_ui_panel_enabled();
+
+ void set_service_ipc(CServiceIpcDbus* ipc) { mServiceIpc = ipc; }
+ CServiceIpcDbus* get_service_ipc() { return mServiceIpc; }
+
+ void set_service_main(CServiceMain* main) { mServiceMain = main; }
+ CServiceMain* get_service_main() { return mServiceMain; }
+private:
+#ifdef BUF_SAVE_MODE
+ char mDumpFilename[128]{'\0', };
+ FILE* mDumpFile{NULL};
+ int mDumpCount{1};
+#endif
+
+ void* mPluginHandle{NULL};
+
+ wakeup_manager_interface mWakeupManagerInterface{NULL, };
+ ma_plugin_settings* mPluginSettings{NULL};
+
+ CServiceIpcDbus* mServiceIpc{nullptr};
+ CServiceMain* mServiceMain{nullptr};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SERVICE_PLUGIN_H__ */
/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ * Copyright 2020 Samsung Electronics Co., Ltd
*
* Licensed under the Flora License, Version 1.1 (the License);
* you may not use this file except in compliance with the License.
*/
-#ifndef _MULTI_ASSISTANT_SERVICE_PLUGIN_H_
-#define _MULTI_ASSISTANT_SERVICE_PLUGIN_H_
+#ifndef __SERVICE_PLUGIN_INTERFACE_H__
+#define __SERVICE_PLUGIN_INTERFACE_H__
-#include <dlog/dlog.h>
-#include <multi_assistant_service.h>
-
-#include "multi_wakeup_recognizer.h"
-#include "multi_assistant_main.h"
+#include <tzplatform_config.h>
#ifdef __cplusplus
extern "C" {
bool ui_panel_enabled;
} ma_plugin_settings;
-int multi_assistant_service_plugin_initialize(void);
-
-int multi_assistant_service_plugin_deinitialize(void);
-
-int multi_assistant_service_plugin_get_settings(ma_plugin_settings **settings, size_t *struct_size);
-
-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_add_assistant_language(const char* appid, const char* language);
-
-int multi_assistant_service_plugin_set_assistant_wakeup_engine(const char* appid, const char* engine);
-
-int multi_assistant_service_plugin_set_default_assistant(const char* appid);
-
-int multi_assistant_service_plugin_get_default_assistant(const char** appid);
-
-int multi_assistant_service_plugin_activate(void);
-
-int multi_assistant_service_plugin_deactivate(void);
-
-int multi_assistant_service_plugin_update_voice_feedback_state(const char* appid, int state);
-
-int multi_assistant_service_plugin_set_assistant_specific_command(const char *appid, const char* command);
-
-int multi_assistant_service_plugin_set_background_volume(const char *appid, double ratio);
-
-int multi_assistant_service_plugin_update_recognition_result(const char* appid, int result);
-
-int multi_assistant_service_plugin_set_preprocessing_allow_mode(const char* appid, int mode, const char* preprocessing_appid);
-
-int multi_assistant_service_plugin_process_event(int event, void* data, int len);
-
-int multi_assistant_service_plugin_start_streaming_utterance_data(void);
-
-int multi_assistant_service_plugin_stop_streaming_utterance_data(void);
-
-int multi_assistant_service_plugin_start_streaming_previous_utterance_data(void);
-
-int multi_assistant_service_plugin_stop_streaming_previous_utterance_data(void);
-
-int multi_assistant_service_plugin_start_streaming_follow_up_data(void);
-
-int multi_assistant_service_plugin_stop_streaming_follow_up_data(void);
-
-int multi_assistant_service_plugin_get_recording_audio_format(int* rate, int* channel, int* audio_type);
-
-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);
-
-int multi_assistant_service_plugin_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
-
-int multi_assistant_service_plugin_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
-
-int multi_assistant_service_plugin_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data);
-
-int multi_assistant_service_plugin_set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data);
-
-int multi_assistant_service_plugin_set_error_callback(wakeup_service_error_cb callback, void* user_data);
-
-
#define MA_WAKEUP_MANAGER_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "multiassistant/")
#define MA_DEFAULT_WAKEUP_MANAGER_FILENAME "libma-wakeup-manager.so"
-
#define MA_WAKEUP_MANAGER_FUNC_INITIALIZE "wakeup_manager_initialize"
typedef int (*wakeup_manager_initialize)(void);
#define MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE "wakeup_manager_deinitialize"
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"
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;
}
#endif
-#endif /* _MULTI_ASSISTANT_SERVICE_PLUGIN_H_ */
+#endif /* __SERVICE_PLUGIN_INTERFACE_H__ */
<?xml version="1.0" encoding="utf-8" ?>
-<manifest xmlns="http://tizen.org/ns/packages" api-version="5.0" package="org.tizen.multi-assistant-service" version="0.2.28">
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.0" package="org.tizen.multi-assistant-service" version="0.2.29">
<label>Multi Assistant Service</label>
<author email="wn.jang@samsung.com" href="www.samsung.com">Won Nam Jang</author>
<author email="sooyeon.kim@samsung.com" href="www.samsung.com">Sooyeon Kim</author>
Name: org.tizen.multi-assistant-service
Summary: Multi assistant service
-Version: 0.2.28
+Version: 0.2.29
Release: 1
Group: Graphics & UI Framework/Voice Framework
License: Flora-1.1
BuildRequires: pkgconfig(multi-assistant)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(pkgmgr-info)
-
+BuildRequires: boost-devel
+%if %{defined _test_type}
+BuildRequires: gtest-devel
+%endif
BuildRequires: boost-system
BuildRequires: boost-thread
BuildRequires: cmake
export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
%endif
+export CFLAGS+=" -Wno-format-truncation -Wno-stringop-truncation -Wno-format-overflow"
+export CXXFLAGS+=" -Wno-format-truncation -Wno-stringop-truncation -Wno-format-overflow"
+
export LDFLAGS
%cmake \
-DCMAKE_INSTALL_PREFIX=%{_appdir} \
-DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE \
+%if %{defined _test_type}
+ -DTEST_TYPE="%{_test_type}" \
+%else
+ -DTEST_TYPE="none" \
+%endif
make %{?jobs:-j%jobs}
%make_install
+%check
+%if "%{_ctest_enable}" == "true"
+ctest --output-on-failure %{?_smp_mflags}
+%endif
+
%post
mkdir -p %{_appbindir}
mkdir -p %{_libdir}/multiassistant/ma/1.0/engine
static thread g_recorder_thread;
static atomic_bool g_stop_recorder_thread{false};
-static long get_current_milliseconds_after_epoch()
+static long long get_current_milliseconds_after_epoch()
{
- auto now = chrono::system_clock::now();
+ auto now = chrono::steady_clock::now();
auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
/* number of milliseconds since the epoch of system_clock */
auto value = now_ms.time_since_epoch();
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();
+ long long int milliseconds = chrono::duration_cast<chrono::milliseconds>(diff).count();
LOGD("milliseconds : %lld", milliseconds);
- mas_plugin_event_e event;
+ mas_plugin_event_e plugin_event;
if (milliseconds < g_voice_key_tap_duration) {
- event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP;
+ plugin_event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP;
} else {
- event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH;
+ plugin_event = MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH;
}
if (g_proxy_interface.process_event) {
- g_proxy_interface.process_event(event, NULL, 0);
+ g_proxy_interface.process_event(plugin_event, NULL, 0);
}
}
}
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
+}
#ifndef _WAKEUP_AUDIO_MANAGER_H_
#define _WAKEUP_AUDIO_MANAGER_H_
+#include "service_common.h"
+
#include <atomic>
#include <list>
#include <mutex>
#include <vector>
#include <multi_assistant_service.h>
-#include <audio_io.h>
-#include <sound_manager.h>
-#include <sound_manager_internal.h>
namespace multiassistant
{
void finalize_audio_data();
void clear_audio_data();
- void start_streaming_current_utterance_data(long start_time = 0);
+ void start_streaming_current_utterance_data(long long start_time = 0);
void stop_streaming_current_utterance_data();
void start_streaming_previous_utterance_data();
void stop_streaming_follow_up_data();
void set_background_volume(double ratio);
-private:
- void add_audio_data(mas_speech_data& data, long time);
+conditional_public:
+ void add_audio_data(mas_speech_data& data, long long time);
void notify_audio_data_recording(long time, void* data, int len);
void streaming_previous_audio_data_thread_func();
- void streaming_audio_data_thread_func(long start_time);
+ void streaming_audio_data_thread_func(long long start_time);
+private:
int mSoundFocusWatchId{0};
bool mRecordingRequired{false};
bool mIsRecording{false};
thread mStreamingPreviousThread;
atomic_bool mStopStreamingPreviousThread{false};
- static constexpr long mAudioRecordingDurationMilliseconds = 10 * 1000;
+ static constexpr long long mAudioRecordingDurationMilliseconds = 10 * 1000;
typedef struct {
- long time;
+ long long time;
mas_speech_data data;
} mas_speech_data_with_time;
vector<mas_speech_data_with_time> mPreviousAudioData;
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"
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;
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);
#ifndef _WAKEUP_MANAGER_H_
#define _WAKEUP_MANAGER_H_
-#include "multi_assistant_config.h"
+#include "service_config.h"
#include "wakeup_manager_wrapper.h"
#include "wakeup_settings.h"
#include "wakeup_engine_manager.h"
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);
bool mVoiceKeyPressed{false};
string mCurrentLanguage;
string mCurrentDefaultAssistant;
- VOICE_KEY_SUPPORT_MODE mCurrentVoiceKeySupportMode;
+ /* Assume Push-to-talk is the default mode */
+ VOICE_KEY_SUPPORT_MODE mCurrentVoiceKeySupportMode{VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK};
STREAMING_MODE mStreamingMode{STREAMING_MODE::NONE};
Ecore_Timer* mStreamingDurationTimer{nullptr};
} // wakeup
} // multiassistant
-#endif /* _WAKEUP_MANAGER_H_ */
\ No newline at end of file
+#endif /* _WAKEUP_MANAGER_H_ */
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);
/*
- * Copyright 2018 Samsung Electronics Co., Ltd
+ * Copyright 2018 Samsung Electronics Co., Ltd
*
* Licensed under the Flora License, Version 1.1 (the License);
* you may not use this file except in compliance with the License.
closure.user_data = user_data;
preference_foreach_item(
- [](const char *key, void *user_data) {
+ [](const char *key, void *data) {
string prefix = string{LANGUAGE_PREFIX};
foreach_assistant_language_cb_closure* closure =
- static_cast<foreach_assistant_language_cb_closure*>(user_data);
+ static_cast<foreach_assistant_language_cb_closure*>(data);
if (key && strlen(key) > prefix.length() &&
0 == prefix.compare(0, prefix.length(), key, prefix.length())) {
char* value = nullptr;
#include <stdexcept>
-#include "multi_assistant_main.h"
+#include "service_common.h"
#include "dependency_resolver.h"
#ifdef LOG_TAG
#include <algorithm>
#include <Ecore.h>
+#include <audio_io.h>
+#include <sound_manager.h>
+#include <sound_manager_internal.h>
namespace multiassistant
{
/* Need to check whether this value needs to be configurable */
static int g_speech_pcm_wait_count = 800;
-static long get_current_milliseconds_after_epoch()
+static long long get_current_milliseconds_after_epoch()
{
- auto now = chrono::system_clock::now();
+ auto now = chrono::steady_clock::now();
auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
/* number of milliseconds since the epoch of system_clock */
auto value = now_ms.time_since_epoch();
unique_lock<mutex> lock(mMutex, defer_lock);
- int ret = -1;
- int cnt = 0;
-
/* get feedback data */
size_t audio_data_size = 0;
lock.lock();
MWR_LOGI("[EXIT]");
}
-void CAudioManager::streaming_audio_data_thread_func(long start_time)
+void CAudioManager::streaming_audio_data_thread_func(long long start_time)
{
MWR_LOGI("[ENTER]");
MWR_LOGI("[EXIT]");
}
-void CAudioManager::add_audio_data(mas_speech_data& data, long time)
+void CAudioManager::add_audio_data(mas_speech_data& data, long long time)
{
- long delta = mAudioRecordingDurationMilliseconds;
+ long long delta = mAudioRecordingDurationMilliseconds;
notify_audio_data_recording(time, data.buffer, data.len);
mas_speech_data speech_data;
speech_data.buffer = vm_malloc_simple(len);
if (speech_data.buffer) {
- long time = get_current_milliseconds_after_epoch();
+ long long time = get_current_milliseconds_after_epoch();
speech_data.event = event;
speech_data.len = len;
speech_data.len = sizeof(final_buffer);
speech_data.buffer = vm_malloc_simple(speech_data.len);
if (speech_data.buffer) {
- long time = get_current_milliseconds_after_epoch();
+ long long time = get_current_milliseconds_after_epoch();
memcpy(speech_data.buffer, final_buffer, speech_data.len);
add_audio_data(speech_data, time);
}
}
-void CAudioManager::start_streaming_current_utterance_data(long start_time)
+void CAudioManager::start_streaming_current_utterance_data(long long start_time)
{
if (mStreamingThread.joinable()) {
MWR_LOGE("ERROR : mStreamingThread is joinable, will not start a new thread");
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");
}
}
}
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);
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]");
return true;
}
-static long get_current_milliseconds_after_epoch()
+static long long get_current_milliseconds_after_epoch()
{
- auto now = chrono::system_clock::now();
+ auto now = chrono::steady_clock::now();
auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
/* number of milliseconds since the epoch of system_clock */
auto value = now_ms.time_since_epoch();
MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP == status) {
mVoiceKeyPressed = false;
}
+ return true;
}
bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len)
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]");
if (nullptr == g_wakeup_manager) return -1;
CWakeupPolicy* policy = g_wakeup_manager->get_wakeup_policy();
if (policy) policy->select_candidate(*wakeup_info);
+ return 0;
}
void CWakeupEventObserver::on_wakeup(mas_wakeup_event_info wakeup_info)
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "application_manager_aul.h"
+#include "service_common.h"
+
+#include <aul.h>
+#include <aul_svc.h>
+
+CApplicationManagerAul::CApplicationManagerAul()
+{
+}
+
+CApplicationManagerAul::~CApplicationManagerAul()
+{
+}
+
+bool CApplicationManagerAul::is_application_running(int pid)
+{
+ int status = aul_app_get_status_bypid(pid);
+ if (0 > status) {
+ MAS_LOGE("The process %d does not exist : %d", pid, status);
+ return false;
+ }
+ return true;
+}
+
+bool CApplicationManagerAul::is_application_running(const std::string& appid)
+{
+ return (!!aul_app_is_running(appid.c_str()));
+}
+
+bool CApplicationManagerAul::bring_app_to_foreground(const std::string& appid)
+{
+ bool ret = true;
+
+ /* Bring MA client to foreground - is there a better way other than launching? */
+ bundle *b = NULL;
+ b = bundle_create();
+ if (NULL == b) {
+ MAS_LOGE("Failed creating bundle for aul operation");
+ return -1;
+ }
+
+ int result = aul_launch_app(appid.c_str(), b);
+ if (result < AUL_R_OK) {
+ MAS_LOGE("ERROR : aul_launch_app failed. app_id [%s] bundle[%p] result[%d : %s]",
+ appid.c_str(), b, result, get_error_message(result));
+ ret = false;
+ }
+
+ if (b) bundle_free(b);
+ b = NULL;
+
+ return ret;
+}
+
+bool CApplicationManagerAul::launch_app_async(const std::string& appid, bool background)
+{
+ bool ret = true;
+
+ bundle *b = NULL;
+ b = bundle_create();
+ if (NULL == b) {
+ MAS_LOGE("Failed creating bundle for aul operation");
+ return false;
+ }
+
+ int result = aul_svc_set_background_launch(b, background);
+ if (result < AUL_R_OK) {
+ MAS_LOGE("ERROR : aul_svc_set_background_launch failed. app_id [%s] bundle[%p] result[%d : %s]",
+ appid.c_str(), b, result, get_error_message(result));
+ }
+
+ result = aul_launch_app_async(appid.c_str(), b);
+ if (result < AUL_R_OK) {
+ MAS_LOGE("ERROR : aul_launch_app_async failed. app_id [%s] bundle[%p] result[%d : %s]",
+ appid.c_str(), b, result, get_error_message(result));
+ ret = false;
+ }
+
+ if (b) bundle_free(b);
+ b = NULL;
+
+ return ret;
+}
+
+boost::optional<std::string> CApplicationManagerAul::get_appid_by_pid(int pid)
+{
+ boost::optional<std::string> ret;
+
+ char appid[MAX_APPID_LEN] = {'\0', };
+ if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
+ appid[MAX_APPID_LEN - 1] = '\0';
+ ret = std::string{appid};
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "client_manager.h"
+#include "service_common.h"
+
+int CClientManager::set_application_manager(IApplicationManager* manager)
+{
+ mApplicationManager = manager;
+ return 0;
+}
+
+int CClientManager::create_client(int pid, std::string appid)
+{
+ ma_client_s* data = NULL;
+
+ try {
+ data = new ma_client_s;
+ } catch(const std::bad_alloc& e) {
+ MAS_LOGE("[ERROR] Fail to allocate memory : %s", e.what());
+ return -1;// MA_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (data) {
+ data->pid = pid;
+ data->appid = appid;
+ mClientList = g_slist_append(mClientList, data);
+ } else {
+ MAS_LOGE("[ERROR] data is NULL");
+ return -1;// MA_ERROR_OUT_OF_MEMORY;
+ }
+
+ return 0;
+}
+
+int CClientManager::destroy_client(ma_client_s* client)
+{
+ if (nullptr == client) {
+ MAS_LOGE("Input parameter is NULL");
+ return -1;// MA_ERROR_OPERATION_FAILED;
+ }
+
+ mClientList = g_slist_remove(mClientList, client);
+
+ delete client;
+
+ return 0;
+}
+
+int CClientManager::destroy_client_by_pid(int pid)
+{
+ ma_client_s* client = find_client_by_pid(pid);
+ return destroy_client(client);
+}
+
+int CClientManager::destroy_client_by_appid(std::string appid)
+{
+ ma_client_s* client = find_client_by_appid(appid);
+ return destroy_client(client);
+}
+
+ma_client_s* CClientManager::find_client_by_appid(std::string appid)
+{
+ ma_client_s *data = NULL;
+
+ int count = g_slist_length(mClientList);
+ int i;
+
+ for (i = 0; i < count; i++) {
+ data = static_cast<ma_client_s*>(g_slist_nth_data(mClientList, i));
+
+ if (NULL != data) {
+ if (0 == appid.compare(data->appid)) {
+ return data;
+ }
+ }
+ }
+
+ MAS_LOGE("[ERROR] client Not found");
+
+ return NULL;
+}
+
+ma_client_s* CClientManager::find_client_by_pid(int pid)
+{
+ ma_client_s *data = NULL;
+
+ int count = g_slist_length(mClientList);
+ int i;
+
+ for (i = 0; i < count; i++) {
+ data = static_cast<ma_client_s*>(g_slist_nth_data(mClientList, i));
+
+ if (NULL != data) {
+ if (data->pid == pid) {
+ return data;
+ }
+ }
+ }
+
+ MAS_LOGE("[ERROR] client Not found");
+
+ return NULL;
+}
+
+int CClientManager::get_client_num()
+{
+ return g_slist_length(mClientList);
+}
+
+ma_client_s* CClientManager::get_client_by_index(unsigned int index)
+{
+ return static_cast<ma_client_s*>(g_slist_nth_data(mClientList, index));
+}
+
+int CClientManager::find_client_pid_by_index(unsigned int index)
+{
+ int pid = -1;
+ ma_client_s* client = get_client_by_index(index);
+ if (client) {
+ pid = client->pid;
+ }
+ return pid;
+}
+
+int CClientManager::find_client_pid_by_appid(std::string appid)
+{
+ int pid = -1;
+
+ if (nullptr == mApplicationManager) {
+ MAS_LOGE("ApplicationManager is NULL, can't check if app is running or not");
+ return pid;
+ }
+
+ ma_client_s* client = find_client_by_appid(appid);
+ if (client) {
+ bool running = mApplicationManager->is_application_running(pid);
+ if (false == running) {
+ MAS_LOGE("The PID for %s was %d, but it seems to be terminated",
+ appid.c_str(), client->pid);
+ } else {
+ pid = client->pid;
+ }
+ }
+ return pid;
+}
+
+std::string CClientManager::find_client_appid_by_pid(int pid)
+{
+ std::string appid;
+
+ if (nullptr == mApplicationManager) {
+ MAS_LOGE("ApplicationManager is NULL, can't check if app is running or not");
+ return appid;
+ }
+
+ ma_client_s* client = find_client_by_pid(pid);
+ if (client) {
+ bool running = mApplicationManager->is_application_running(pid);
+ if (false == running) {
+ MAS_LOGE("The appid for %d was %s, but it seems to be terminated",
+ pid, client->appid.c_str());
+ } else {
+ appid = client->appid;
+ }
+ }
+ return appid;
+}
+
+bool CClientManager::check_client_validity_by_appid(std::string appid)
+{
+ int pid = find_client_pid_by_appid(appid);
+ if (0 < pid) return true;
+ return false;
+}
--- /dev/null
+/*
+ * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <tizen.h>
+#include <service_app.h>
+
+#include "service_main.h"
+#include "application_manager_aul.h"
+#include "preference_manager_vconf.h"
+
+CApplicationManagerAul g_application_manager_aul;
+CPreferenceManagerVconf g_preference_manager_vconf;
+CServiceMain g_service_main{g_application_manager_aul, g_preference_manager_vconf};
+
+static bool service_app_create(void *data)
+{
+ return g_service_main.app_create(data);
+}
+
+static void service_app_terminate(void *data)
+{
+ return g_service_main.app_terminate(data);
+}
+
+static void service_app_control(app_control_h app_control, void *data)
+{
+ // Todo: add your code here.
+ return;
+}
+
+static void service_app_lang_changed(app_event_info_h event_info, void *user_data)
+{
+ /*APP_EVENT_LANGUAGE_CHANGED*/
+ return;
+}
+
+static void service_app_region_changed(app_event_info_h event_info, void *user_data)
+{
+ /*APP_EVENT_REGION_FORMAT_CHANGED*/
+}
+
+static void service_app_low_battery(app_event_info_h event_info, void *user_data)
+{
+ /*APP_EVENT_LOW_BATTERY*/
+}
+
+static void service_app_low_memory(app_event_info_h event_info, void *user_data)
+{
+ /*APP_EVENT_LOW_MEMORY*/
+}
+
+int main(int argc, char* argv[])
+{
+ char ad[50] = {0, };
+ service_app_lifecycle_callback_s event_callback;
+ app_event_handler_h handlers[5] = {NULL, };
+
+ event_callback.create = service_app_create;
+ event_callback.terminate = service_app_terminate;
+ event_callback.app_control = service_app_control;
+
+ service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
+ service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
+ service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
+ service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
+
+ int ret = service_app_main(argc, argv, &event_callback, ad);
+ LOGI("Main function exits with : %d", ret);
+ return ret;
+}
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <libxml/parser.h>
-#include <sys/types.h>
-#include <dirent.h>
-
-#include "multi_assistant_config.h"
-#include "multi_assistant_main.h"
-
-int mas_config_parse_assistant_info(mas_config_assistant_info_cb callback, const char *path, void* user_data)
-{
- xmlDocPtr doc = NULL;
- xmlNodePtr cur = NULL;
- xmlChar *key;
-
- int loop;
- int retry_count = 0;
-
- while (NULL == doc) {
- doc = xmlParseFile(path);
- if (NULL != doc) {
- break;
- }
-
- if (MA_RETRY_COUNT == retry_count++) {
- MAS_LOGE("[ERROR] Fail to parse file error : %s", path);
- xmlCleanupParser();
- return -1;
- }
- usleep(10000);
- }
-
- cur = xmlDocGetRootElement(doc);
- if (cur == NULL) {
- MAS_LOGE("[ERROR] Empty document");
- xmlFreeDoc(doc);
- return -1;
- }
-
- if (xmlStrcmp(cur->name, (const xmlChar *) MA_TAG_ASSISTANT_BASE)) {
- MAS_LOGE("[ERROR] The wrong type, root node is NOT %s", MA_TAG_ASSISTANT_BASE);
- xmlFreeDoc(doc);
- return -1;
- }
-
- cur = cur->xmlChildrenNode;
- if (cur == NULL) {
- MAS_LOGE("[ERROR] Empty document");
- xmlFreeDoc(doc);
- return -1;
- }
-
- /* alloc assistant info */
- 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)) {
- xmlNodePtr child_node = cur->xmlChildrenNode;
- while (child_node != NULL) {
- 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);
- MAS_LOGD("Language : %s", key);
- xmlFree(key);
- }
- }
-
- child_node = child_node->next;
- }
- } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar *)MA_TAG_ASSISTANT_WAKEUP_WORD_SET)) {
- xmlNodePtr child_node = cur->xmlChildrenNode;
- while (child_node != NULL) {
- 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);
- 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);
- xmlFree(prop);
- }
- temp.cnt_wakeup++;
- }
-
- child_node = child_node->next;
- }
- } 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);
- 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);
- 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);
- 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);
- MAS_LOGD("Wakeup Engine : %s", key);
- xmlFree(key);
- }
- } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_CUSTOM_UI)) {
- key = xmlNodeGetContent(cur);
- if (key) {
- if (0 == xmlStrcasecmp(key, "true")) {
- temp.custom_ui_option = true;
- }
- 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);
- }
- }
-
- cur = cur->next;
- }
-
- if (callback) {
- callback(&temp, user_data);
- }
-
- if (temp.app_id) {
- free((void*)temp.app_id);
- }
- if (temp.name) {
- free((void*)temp.name);
- }
- 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_lang; loop++) {
- if (temp.supported_lang[loop]) {
- free((void*)(temp.supported_lang[loop]));
- }
- }
- if (temp.wakeup_engine) {
- free((void*)temp.wakeup_engine);
- }
-
- xmlFreeDoc(doc);
-
- return 0;
-}
-
-int mas_config_get_assistant_info(mas_config_assistant_info_cb callback, void* user_data)
-{
- const char *suffix = ".xml";
-
- DIR *d;
- struct dirent *dir;
- d = opendir(MA_ASSISTANT_INFO);
-
- if (d) {
- while (NULL != (dir = readdir(d))) {
- if (suffix && strlen(suffix) <= strlen(dir->d_name)) {
- if (0 == strcmp(dir->d_name + strlen(dir->d_name) - strlen(suffix), suffix)) {
- char fullpath[_POSIX_PATH_MAX];
- snprintf(fullpath, _POSIX_PATH_MAX - 1, "%s/%s", MA_ASSISTANT_INFO, dir->d_name);
- MAS_LOGD("Parsing file : %s\n", fullpath);
- mas_config_parse_assistant_info(callback, fullpath, user_data);
- }
- }
- }
- closedir(d);
- }
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __MULTI_ASSISTANT_DBUS_h__
-#define __MULTI_ASSISTANT_DBUS_h__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int mas_dbus_open_connection();
-
-int mas_dbus_close_connection();
-
-int masc_dbus_send_hello(int pid);
-
-int masc_dbus_send_error_message(int reason, const char* err_msg);
-
-int masc_dbus_send_streaming_audio_data(int pid, int event, unsigned char* data, unsigned int data_size);
-
-int masc_dbus_active_state_change(int pid, int state);
-
-int masc_dbus_send_preprocessing_information(int pid, const char* app_id);
-
-int masc_dbus_send_streaming_section_changed(int pid, int section);
-
-int masc_dbus_send_preprocessing_result(int pid, bool result);
-
-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);
-
-int masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json);
-
-int masc_ui_dbus_change_assistant(char* app_id);
-
-int masc_ui_dbus_send_error_message(int reason, const char* err_msg);
-
-int masc_ui_dbus_send_recognition_result(int pid, int result);
-
-int masc_ui_dbus_enable_common_ui(int enable);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MULTI_ASSISTANT_DBUS_h__ */
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __MULTI_ASSISTANT_DBUS_SERVER_H__
-#define __MULTI_ASSISTANT_DBUS_SERVER_H__
-
-#include <dbus/dbus.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int ma_service_dbus_hello(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_initialize(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_get_audio_format(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_get_audio_source_type(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_send_asr_result(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_send_result(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_send_recognition_result(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_send_assistant_specific_command(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_set_background_volume(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_set_preprocessing_allow_mode(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_dbus_send_preprocessing_result(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_ui_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg);
-
-int ma_service_ui_dbus_change_assistant(DBusConnection* conn, DBusMessage* msg);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __MULTI_ASSISTANT_DBUS_SERVER_H__ */
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <tizen.h>
-#include <service_app.h>
-#include <app_manager.h>
-#include <app.h>
-#include <aul.h>
-#include <malloc.h>
-#include <Ecore.h>
-#include <vconf.h>
-#include <package_manager.h>
-#include <pkgmgr-info.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#include "multi_assistant_main.h"
-#include "multi_assistant_service_client.h"
-#include "multi_assistant_service_plugin.h"
-#include "multi_assistant_dbus.h"
-#include "multi_assistant_config.h"
-
-static const char *g_current_lang = "en_US";
-
-#define ENABLE_MULTI_ASSISTANT_BY_DEFAULT
-
-#define MULTI_ASSISTANT_SETTINGS_ACTIVATED "db/multi-assistant/activated"
-#define WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID "db/multi-assistant/preprocessing_assistant_appid"
-#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];
- char wakeup_word[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN];
- char wakeup_language[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
- 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];
-} ma_client_info;
-
-static ma_client_info g_maclient_info[MAX_MACLIENT_INFO_NUM];
-
-typedef struct {
- int pid;
- char appid[MAX_APPID_LEN];
-} ma_client_s;
-
-static int g_current_maclient_info = 0;
-static int g_current_preprocessing_maclient_info = -1;
-static const char *g_wakeup_maclient_appid = NULL;
-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;
-
-int ma_client_create(ma_client_s *info)
-{
- if (NULL == info) {
- MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
- return -1;
- }
-
- ma_client_s* data = NULL;
-
- data = (ma_client_s*)calloc(1, sizeof(ma_client_s));
- if (NULL == data) {
- MAS_LOGE("[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
- return -1;// MA_ERROR_OUT_OF_MEMORY;
- }
-
- *data = *info;
- g_client_list = g_slist_append(g_client_list, data);
-
- return 0;
-}
-
-int ma_client_destroy(ma_client_s *client)
-{
- if (NULL == client) {
- MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
- return -1;// MA_ERROR_OPERATION_FAILED;
- }
-
- g_client_list = g_slist_remove(g_client_list, client);
-
- free(client);
- client = NULL;
-
- return 0;
-}
-
-ma_client_s* ma_client_find_by_appid(const char *appid)
-{
- if (NULL == appid) {
- MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
- return NULL;
- }
-
- ma_client_s *data = NULL;
-
- int count = g_slist_length(g_client_list);
- int i;
-
- for (i = 0; i < count; i++) {
- data = g_slist_nth_data(g_client_list, i);
-
- if (NULL != data) {
- if (0 == strncmp(data->appid, appid, MAX_APPID_LEN)) {
- return data;
- }
- }
- }
-
- MAS_LOGE("[ERROR] client Not found");
-
- return NULL;
-}
-
-ma_client_s* ma_client_find_by_pid(int pid)
-{
- ma_client_s *data = NULL;
-
- int count = g_slist_length(g_client_list);
- int i;
-
- for (i = 0; i < count; i++) {
- data = g_slist_nth_data(g_client_list, i);
-
- if (NULL != data) {
- if (data->pid == pid) {
- return data;
- }
- }
- }
-
- MAS_LOGE("[ERROR] client Not found");
-
- return NULL;
-}
-
-bool check_preprocessing_assistant_exists()
-{
- bool ret = false;
-
- char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
- if (vconf_str) {
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- if (g_maclient_info[loop].used) {
- if (strncmp(vconf_str, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- ma_client_s* client = ma_client_find_by_appid(vconf_str);
- if (client && client->pid > 0) {
- ret = true;
- }
- }
- }
- }
- free(vconf_str);
- vconf_str = NULL;
- }
-
- MAS_LOGD("result : %d", ret);
-
- return ret;
-}
-
-bool is_current_preprocessing_assistant(const char* appid)
-{
- if (NULL == appid) return false;
-
- bool ret = false;
-
- char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
- if (vconf_str) {
- if (strncmp(vconf_str, appid, MAX_APPID_LEN) == 0) {
- ret = true;
- }
- free(vconf_str);
- vconf_str = NULL;
- }
-
- return ret;
-}
-
-int mas_client_initialize(int pid)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- char appid[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
- appid[MAX_APPID_LEN - 1] = '\0';
-
- MAS_LOGD("appid for pid %d is : %s", pid, (appid ? appid : "Unknown"));
-
- /* Remove existing client that has same appid, if there's any */
- ma_client_s *old_client = NULL;
- old_client = ma_client_find_by_appid(appid);
- if (old_client) {
- ma_client_destroy(old_client);
- old_client = NULL;
- }
-
- /* And remove a client that has same pid also */
- old_client = ma_client_find_by_pid(pid);
- if (old_client) {
- ma_client_destroy(old_client);
- old_client = NULL;
- }
-
- ma_client_s new_client;
- new_client.pid = pid;
- strncpy(new_client.appid, appid, MAX_APPID_LEN);
- new_client.appid[MAX_APPID_LEN - 1] = '\0';
- ma_client_create(&new_client);
-
- const char *current_maclient_appid = NULL;
- if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
- current_maclient_appid = g_maclient_info[g_current_maclient_info].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);
- }
- if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) {
- MAS_LOGD("MA client with current maclient appid connected!");
-
- if (g_wakeup_maclient_appid && strncmp(g_wakeup_maclient_appid, appid, MAX_APPID_LEN) == 0) {
- g_wakeup_maclient_appid = NULL;
- mas_client_activate(pid);
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
- } else {
- MAS_LOGE("[ERROR] g_wakeup_maclient_appid and appid differ : %s %s",
- (g_wakeup_maclient_appid ? g_wakeup_maclient_appid : "NULL"), appid);
- }
- } else {
- MAS_LOGD("MA client connected, but its appid does not match with current maclient");
- }
-
- masc_dbus_service_state_change(pid, mas_get_current_service_state());
- } else {
- MAS_LOGE("[ERROR] Fail to retrieve appid");
- }
-
- return 0;
-}
-
-int mas_client_deinitialize(int pid)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
- ma_client_s *client = ma_client_find_by_pid(pid);
- if (client) {
- ma_client_destroy(client);
- client = NULL;
- }
- return 0;
-}
-
-int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- int ret = multi_assistant_service_plugin_get_recording_audio_format(rate, channel, audio_type);
- if (0 != ret){
- MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret);
- }
-
- return ret;
-}
-
-#define MAX_LOCAL_VARIABLE_STRING_LEN 256
-int mas_client_get_audio_source_type(int pid, char** type)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- if (NULL == type) return -1;
-
- static char cached[MAX_LOCAL_VARIABLE_STRING_LEN] = {'\0'};
- int ret = multi_assistant_service_plugin_get_recording_audio_source_type(type);
- if (0 != ret){
- MAS_LOGE("[ERROR] Fail to get recording audio source type, ret(%d)", ret);
- *type = cached;
- } else if (*type) {
- strncpy(cached, *type, MAX_LOCAL_VARIABLE_STRING_LEN - 1);
- cached[MAX_LOCAL_VARIABLE_STRING_LEN - 1] = '\0';
- }
-
- return ret;
-}
-
-int mas_client_send_preprocessing_information(int pid)
-{
- int ret = -1;
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
- MAS_LOGD("preprocessing_assistant_appid : %s", vconf_str);
- if (vconf_str) {
- ret = masc_dbus_send_preprocessing_information(pid, vconf_str);
- free(vconf_str);
- vconf_str = NULL;
- }
-
- 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;
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- ret = masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_ACTIVE);
-
- return ret;
-}
-
-int mas_client_deactivate(int pid)
-{
- int ret = -1;
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- ret = masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_INACTIVE);
-
- return ret;
-}
-
-int mas_client_send_asr_result(int pid, int event, char* asr_result)
-{
- MAS_LOGD("[Enter] pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
- int ret = masc_ui_dbus_send_asr_result(pid, event, asr_result);
- if (0 != ret){
- MAS_LOGE("[ERROR] Fail to send asr result, ret(%d)", ret);
- }
-
- // if final event is , launch assistant app which is invoked with wakeup word.
- /* TO_DO */
- return ret;
-}
-
-int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json)
-{
- MAS_LOGD("[Enter] pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
- int ret = masc_ui_dbus_send_result(pid, display_text, utterance_text, result_json);
- if (0 != ret){
- MAS_LOGE("[ERROR] Fail to send result, ret(%d)", ret);
- }
-
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- multi_assistant_service_plugin_update_recognition_result(pid_appid, MA_RECOGNITION_RESULT_EVENT_SUCCESS);
-
- return ret;
-}
-
-int mas_client_send_recognition_result(int pid, int result)
-{
- MAS_LOGD("[Enter] pid(%d), result(%d)", pid, result);
- int ret = masc_ui_dbus_send_recognition_result(pid, result);
- if (0 != ret){
- MAS_LOGE("[ERROR] Fail to send recognition result, ret(%d)", ret);
- }
-
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- multi_assistant_service_plugin_update_recognition_result(pid_appid, result);
-
- return ret;
-}
-
-int mas_client_start_streaming_audio_data(int pid, int type)
-{
- int ret = -1;
- switch(type) {
- case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
- ret = multi_assistant_service_plugin_start_streaming_utterance_data();
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED);
- break;
- case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
- ret = multi_assistant_service_plugin_start_streaming_previous_utterance_data();
- /* Preprocessing is not required for previous utterance streaming */
- break;
- case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
- ret = multi_assistant_service_plugin_start_streaming_follow_up_data();
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED);
- break;
- }
- return ret;
-}
-
-int mas_client_stop_streaming_audio_data(int pid, int type)
-{
- int ret = -1;
- switch(type) {
- case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
- ret = multi_assistant_service_plugin_stop_streaming_utterance_data();
- break;
- case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
- ret = multi_assistant_service_plugin_stop_streaming_previous_utterance_data();
- break;
- case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
- ret = multi_assistant_service_plugin_stop_streaming_follow_up_data();
- break;
- }
- return ret;
-}
-
-int mas_client_update_voice_feedback_state(int pid, int state)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- multi_assistant_service_plugin_update_voice_feedback_state(pid_appid, state);
- return 0;
-}
-
-int mas_client_set_assistant_specific_command(int pid, const char *command)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- multi_assistant_service_plugin_set_assistant_specific_command(pid_appid, command);
- return 0;
-}
-
-int mas_client_set_background_volume(int pid, double ratio)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- multi_assistant_service_plugin_set_background_volume(pid_appid, ratio);
- return 0;
-}
-
-int mas_client_set_preprocessing_allow_mode(int pid, int mode, const char* appid)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- 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) {
- if (pid_appid && strncmp(pid_appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- g_maclient_info[loop].preprocessing_allow_mode = mode;
- if (appid) {
- strncpy(g_maclient_info[loop].preprocessing_allow_appid, appid, MAX_APPID_LEN);
- g_maclient_info[loop].preprocessing_allow_appid[MAX_APPID_LEN - 1] = '\0';
- } else {
- g_maclient_info[loop].preprocessing_allow_appid[0] = '\0';
- }
- }
- }
- }
-
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED);
-
- return 0;
-}
-
-int mas_client_send_preprocessing_result(int pid, bool result)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
- if (!is_current_preprocessing_assistant(pid_appid)) return -1;
-
- const char *current_maclient_appid = NULL;
- if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
- current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
- }
-
- if (result) {
- MAS_LOGD("Preprocessing succeeded, bring (%s) to foreground", pid_appid);
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED);
- } else {
- MAS_LOGD("Preprocessing failed, bring (%s) to foreground", current_maclient_appid);
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED);
- }
-
- ma_client_s* client = ma_client_find_by_appid(current_maclient_appid);
- if (client) {
- masc_dbus_send_preprocessing_result(client->pid, result);
- }
-
- return 0;
-}
-
-int mas_client_set_wake_word_audio_require_flag(int pid, bool require)
-{
- const char* pid_appid = NULL;
- char buf[MAX_APPID_LEN] = {'\0',};
- if (AUL_R_OK == aul_app_get_appid_bypid(pid, buf, sizeof(buf))) {
- buf[MAX_APPID_LEN - 1] = '\0';
- pid_appid = buf;
- }
-
- multi_assistant_service_plugin_set_wake_word_audio_require_flag(pid_appid, require);
- return 0;
-}
-
-int mas_client_set_assistant_language(int pid, 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;
- }
-
- multi_assistant_service_plugin_assistant_language(pid_appid, language);
- return 0;
-}
-
-int mas_ui_client_initialize(int pid)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- return 0;
-}
-
-int mas_ui_client_deinitialize(int pid)
-{
- MAS_LOGD("[Enter] pid(%d)", pid);
-
- return 0;
-}
-
-int mas_ui_client_change_assistant(const char* appid)
-{
- MAS_LOGD("[Enter]");
-
- if (NULL == appid) {
- MAS_LOGE("NULL parameter");
- return -1;
- }
-
- bool use_custom_ui = mas_get_client_custom_ui_option_by_appid(appid);
- masc_ui_dbus_enable_common_ui(!use_custom_ui);
-
- mas_set_current_client_by_appid(appid);
- int pid = mas_get_client_pid_by_appid(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"));
- /*
- int ret = multi_assistant_service_plugin_start_streaming_utterance_data();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to start streaming utterance data(%d)", ret);
- }
- */
- } else {
- // Appropriate MA Client not available, trying to launch new one
- MAS_LOGD("MA Client with appid %s does not exist, launching client", (appid ? appid : "NULL"));
-
- /* The appid parameter might not exist after this function call, so we use appid string in our g_maclient_info */
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid) &&
- 0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
- if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- mas_launch_client_by_appid(g_maclient_info[loop].appid, CLIENT_LAUNCH_MODE_ACTIVATION);
- }
- }
- }
- }
-
- return 0;
-}
-
-int __mas_assistant_info_cb(ma_assistant_info_s* info, void* user_data) {
- MAS_LOGD("__mas_assistant_info_cb called");
-
- if (NULL == info) {
- MAS_LOGE("info NULL, returning");
- return -1;
- }
- if (NULL == info->app_id) {
- MAS_LOGE("app_id NULL, returning");
- return -1;
- }
-
- int index = -1;
- int loop = 0;
- while(-1 == index && loop < MAX_MACLIENT_INFO_NUM) {
- if (false == g_maclient_info[loop].used) {
- index = loop;
- }
- loop++;
- }
- if (-1 != index) {
- 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)", 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)) {
- g_current_preprocessing_maclient_info = index;
- }
-
- for (loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
- 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 (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);
- }
- } else {
- strncpy(g_maclient_info[index].wakeup_word[loop], "", MAX_WAKEUP_WORD_LEN);
- }
- }
-
- for (loop = 0;loop < MAX_SUPPORTED_LANGUAGES_NUM;loop++) {
- 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)", 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", info->app_id);
- }
- 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");
- }
-
- MAS_LOGD("__mas_assistant_info_cb end");
-
- return 0;
-}
-
-static void mas_active_state_changed_cb(keynode_t* key, void* data)
-{
- int vconf_value = 0;
- if (vconf_get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED, &vconf_value) == 0) {
- MAS_LOGD("multi-assistant active state : %d\n", vconf_value);
-
- if (vconf_value) {
- multi_assistant_service_plugin_activate();
- } else {
- multi_assistant_service_plugin_deactivate();
- }
- }
-}
-
-static int init_plugin(void)
-{
- if (0 != multi_assistant_service_plugin_initialize()) {
- MAS_LOGE("Fail to ws intialize");
- return -1;
- }
-
- if (0 != multi_assistant_service_plugin_set_language(g_current_lang)) {
- MAS_LOGE("Fail to ws set language");
- return -1;
- }
-
- if (0 == mas_config_get_assistant_info(__mas_assistant_info_cb, NULL)) {
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- int inner_loop;
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- if (0 < strlen(g_maclient_info[loop].wakeup_engine)) {
- multi_assistant_service_plugin_set_assistant_wakeup_engine(
- g_maclient_info[loop].appid,
- g_maclient_info[loop].wakeup_engine);
- }
- for (inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
- MAS_LOGD("Registering wakeup word %s for app %s",
- g_maclient_info[loop].wakeup_word[inner_loop], g_maclient_info[loop].appid);
- if (0 != multi_assistant_service_plugin_add_assistant_wakeup_word(
- g_maclient_info[loop].appid,
- g_maclient_info[loop].wakeup_word[inner_loop],
- g_maclient_info[loop].wakeup_language[inner_loop])) {
- MAS_LOGE("Fail to add assistant's wakeup word");
- }
- }
- }
- for (inner_loop = 0; inner_loop < MAX_SUPPORTED_LANGUAGE_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].supported_language[inner_loop])) {
- MAS_LOGD("Adding language %s for app %s",
- g_maclient_info[loop].supported_language[inner_loop], g_maclient_info[loop].appid);
- if (0 != multi_assistant_service_plugin_add_assistant_language(
- g_maclient_info[loop].appid,
- g_maclient_info[loop].supported_language[inner_loop])) {
- MAS_LOGE("Fail to add assistant's language");
- }
- }
- }
- }
- }
- } else {
- MAS_LOGE("Fail to load assistant info");
- }
-
- if (0 != multi_assistant_service_plugin_set_callbacks()) {
- MAS_LOGE("Fail to set callbacks");
- return -1;
- }
-
- return 0;
-}
-
-static int deinit_plugin(void)
-{
- MAS_LOGI("[ENTER]");
- if (0 != multi_assistant_service_plugin_deactivate()) {
- MAS_LOGE("Fail to deactivate");
- }
- if (0 != multi_assistant_service_plugin_deinitialize()) {
- MAS_LOGE("Fail to deinitialize");
- }
- MAS_LOGI("[END]");
- return 0;
-}
-
-static int process_activated_setting()
-{
- if (0 == vconf_notify_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb, NULL)) {
- /* Activate / deactivate according to the vconf key setting */
- mas_active_state_changed_cb(NULL, NULL);
- } else {
-#ifdef ENABLE_MULTI_ASSISTANT_BY_DEFAULT
- /* Multi-assistant needs to be enabled by default, unless disabled explicitly */
- multi_assistant_service_plugin_activate();
- const char *default_assistant = NULL;
- if (0 == multi_assistant_service_plugin_get_default_assistant(&default_assistant)) {
- if (NULL == default_assistant) {
- if (g_maclient_info[0].used) {
- default_assistant = g_maclient_info[0].appid;
- MAS_LOGW("No default assistant, setting %s as default", default_assistant);
- multi_assistant_service_plugin_set_default_assistant(default_assistant);
- } else {
- MAS_LOGE("No default assistant, and no assistant installed");
- }
- }
- }
-#endif
- }
- return 0;
-}
-
-static int init_wakeup(void)
-{
- MAS_LOGD("[Enter] init_wakeup");
-
- int ret = mas_dbus_open_connection();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to open connection");
- }
-
- init_plugin();
-
- 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;
- vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
- if (vconf_str) {
- MAS_LOGD("prelaunching preprocessing_assistant_appid : %s", vconf_str);
- mas_launch_client_by_appid(vconf_str, CLIENT_LAUNCH_MODE_PRELAUNCH);
- free(vconf_str);
- vconf_str = NULL;
- }
-
- return 0;
-}
-
-static void deinit_wakeup(void)
-{
- MAS_LOGI("[Enter] deinit_wakeup");
-
-/* if (NULL != g_current_lang) {
- free(g_current_lang);
- g_current_lang = NULL;
- }
-*/
- deinit_plugin();
-
- vconf_ignore_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb);
-
- int ret = mas_dbus_close_connection();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to close connection");
- }
- MAS_LOGI("[END]");
-}
-
-int mas_get_current_client_pid()
-{
- int ret = -1;
- if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
- const char *appid = g_maclient_info[g_current_maclient_info].appid;
- ma_client_s* client = ma_client_find_by_appid(appid);
- if (client) {
- ret = client->pid;
- }
- }
- return ret;
-}
-
-int mas_get_current_preprocessing_client_pid()
-{
- int ret = -1;
- if (g_current_preprocessing_maclient_info >= 0 && g_current_preprocessing_maclient_info < MAX_MACLIENT_INFO_NUM) {
- const char *appid = g_maclient_info[g_current_preprocessing_maclient_info].appid;
- ma_client_s* client = ma_client_find_by_appid(appid);
- if (client) {
- ret = client->pid;
- }
- }
- return ret;
-}
-
-int mas_get_client_pid_by_appid(const char *appid)
-{
- int ret = -1;
-
- if (appid) {
- ma_client_s *client = NULL;
- client = ma_client_find_by_appid(appid);
- if (client) {
- ret = client->pid;
- }
- }
-
- int status = aul_app_get_status_bypid(ret);
- if (-1 != ret && 0 > status) {
- MAS_LOGE("The PID for %s was %d, but it seems to be terminated : %d",
- (appid ? appid : "NULL"), ret, status);
- mas_client_deinitialize(ret);
- ret = -1;
- }
-
- return ret;
-}
-
-const char* mas_get_client_appid_by_pid(int pid)
-{
- const char* ret = NULL;
-
- ma_client_s *client = NULL;
- client = ma_client_find_by_pid(pid);
- if (client) {
- ret = client->appid;
- }
-
- int status = aul_app_get_status_bypid(pid);
- if (-1 != ret && 0 > status) {
- MAS_LOGE("The appid for %d was %s, but it seems to be terminated : %d",
- pid, (ret ? ret : "NULL"), status);
- mas_client_deinitialize(pid);
- ret = NULL;
- }
-
- return ret;
-}
-
-bool mas_get_client_custom_ui_option_by_appid(const char *appid)
-{
- bool ret = false;
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid) &&
- 0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
- if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- ret = g_maclient_info[loop].custom_ui_option;
- }
- }
- }
- return ret;
-}
-
-int mas_get_client_pid_by_wakeup_word(const char *wakeup_word)
-{
- const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
- return mas_get_client_pid_by_appid(appid);
-}
-
-const char* mas_get_client_appid_by_wakeup_word(const char *wakeup_word)
-{
- int loop;
- const char *appid = NULL;
-
- if (NULL == wakeup_word) return NULL;
-
- for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
- if (0 == strncmp(wakeup_word, g_maclient_info[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
- appid = g_maclient_info[loop].appid;
- }
- }
- }
- }
- }
-
- /* Perform extended search, by eliminating blank characters */
- if (NULL == appid) {
- for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
- char comparand[MAX_WAKEUP_WORD_LEN];
- int comparand_index = 0;
- for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
- if (' ' != g_maclient_info[loop].wakeup_word[inner_loop][index]) {
- comparand[comparand_index++] = g_maclient_info[loop].wakeup_word[inner_loop][index];
- }
- }
- if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
- appid = g_maclient_info[loop].appid;
- }
- }
- }
- }
- }
- }
-
- return appid;
-}
-
-int mas_set_current_client_by_wakeup_word(const char *wakeup_word)
-{
- int loop;
- int ret = -1;
- int prev_selection = g_current_maclient_info;
-
- for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
- if (0 == strncmp(wakeup_word, g_maclient_info[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
- g_current_maclient_info = loop;
- ret = 0;
- }
- }
- }
- }
- }
- /* Perform extended search, by eliminating blank characters */
- if (ret == -1) {
- for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
- if (0 < strlen(g_maclient_info[loop].wakeup_word[inner_loop])) {
- char comparand[MAX_WAKEUP_WORD_LEN];
- int comparand_index = 0;
- for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
- if (' ' != g_maclient_info[loop].wakeup_word[inner_loop][index]) {
- comparand[comparand_index++] = g_maclient_info[loop].wakeup_word[inner_loop][index];
- }
- }
- if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
- g_current_maclient_info = loop;
- ret = 0;
- }
- }
- }
- }
- }
- }
-
- if (g_current_maclient_info != prev_selection) {
- if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
- mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
- }
- }
-
- return ret;
-}
-
-int mas_set_current_client_by_appid(const char *appid)
-{
- int ret = -1;
- int prev_selection = g_current_maclient_info;
-
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid) &&
- 0 < strlen(g_maclient_info[loop].wakeup_word[0])) {
- if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- g_current_maclient_info = loop;
- ret = 0;
- }
- }
- }
-
- if (g_current_maclient_info != prev_selection) {
- if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
- mas_client_deactivate(mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid));
- }
- }
-
- return ret;
-}
-
-int mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode)
-{
- if (NULL == appid || 0 == strlen(appid)) {
- MAS_LOGE("appid invalid, failed launching MA Client");
- return -1;
- }
-
- if (CLIENT_LAUNCH_MODE_PRELAUNCH == launch_mode) {
- if (1 == aul_app_is_running(appid)) {
- MAS_LOGE("appid %s is already running, no need for a prelaunch", appid);
- return -1;
- }
- }
-
- bundle *b = NULL;
- b = bundle_create();
- if (NULL == b) {
- MAS_LOGE("Failed creating bundle for aul operation");
- return -1;
- }
-
- int result = aul_svc_set_background_launch(b,
- (CLIENT_LAUNCH_MODE_PRELAUNCH == launch_mode ? TRUE : FALSE));
- if (result < AUL_R_OK) {
- MAS_LOGE("ERROR : aul_svc_set_background_launch failed. app_id [%s] bundle[%p] result[%d : %s]",
- appid, b, result, get_error_message(result));
- }
-
- result = aul_launch_app_async(appid, b);
- if (result < AUL_R_OK) {
- MAS_LOGE("ERROR : aul_launch_app_async failed. app_id [%s] bundle[%p] result[%d : %s]",
- appid, b, result, get_error_message(result));
- }
-
- if (CLIENT_LAUNCH_MODE_ACTIVATION == launch_mode) {
- bool found = false;
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
- if (g_maclient_info[loop].used &&
- 0 < strlen(g_maclient_info[loop].appid)) {
- if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- g_wakeup_maclient_appid = g_maclient_info[loop].appid;
- found = true;
- }
- }
- }
- MAS_LOGD("g_wakeup_maclient_appid : %s, %d", g_wakeup_maclient_appid, found);
- }
-
- if (b) bundle_free(b);
- b = NULL;
-
- return result;
-}
-
-int mas_bring_client_to_foreground(const char* appid)
-{
- /* Bring MA client to foreground - is there a better way other than launching? */
- if (NULL == appid || 0 == strlen(appid)) {
- MAS_LOGE("appid invalid, failed launching MA Client");
- return -1;
- }
-
- bundle *b = NULL;
- b = bundle_create();
- if (NULL == b) {
- MAS_LOGE("Failed creating bundle for aul operation");
- return -1;
- }
-
- int result = aul_launch_app(appid, b);
- if (result < AUL_R_OK) {
- MAS_LOGE("ERROR : aul_launch_app failed. app_id [%s] bundle[%p] result[%d : %s]",
- appid, b, result, get_error_message(result));
- }
-
- if (b) bundle_free(b);
- b = NULL;
-
- return result;
-}
-
-int mas_launch_client_by_wakeup_word(const char *wakeup_word)
-{
- const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
- return mas_launch_client_by_appid(appid, CLIENT_LAUNCH_MODE_ACTIVATION);
-}
-
-int mas_prelaunch_default_assistant()
-{
- /* CHECK NEEDED : should the code segment below and activation logic above be moved to wakeup manger? */
- int prelaunch_mode;
- int res = vconf_get_bool(WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE, &prelaunch_mode);
- if (0 == res && 0 != prelaunch_mode) {
- const char *default_assistant = NULL;
- if (0 == multi_assistant_service_plugin_get_default_assistant(&default_assistant)) {
- if (0 == aul_app_is_running(default_assistant)) {
- MAS_LOGD("prelaunching default_assistant_appid : %s", default_assistant);
- mas_launch_client_by_appid(default_assistant, CLIENT_LAUNCH_MODE_PRELAUNCH);
- }
- }
- }
- 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++) {
- if (appid && g_maclient_info[loop].used) {
- if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) {
- return g_maclient_info[loop].preprocessing_allow_mode;
- }
- }
- }
- return MA_PREPROCESSING_ALLOW_NONE;
-}
-
-/* This might need to be read from settings in the future, but using macro for now */
-//#define BRING_PREPROCESSING_ASSISTANT_TO_FRONT
-
-int mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event)
-{
- const char* current_maclient_appid = NULL;
- const char* preprocessing_allow_appid = NULL;
- if (g_current_maclient_info >= 0 && g_current_maclient_info < MAX_MACLIENT_INFO_NUM) {
- current_maclient_appid = g_maclient_info[g_current_maclient_info].appid;
- preprocessing_allow_appid = g_maclient_info[g_current_maclient_info].preprocessing_allow_appid;
- }
- ma_preprocessing_allow_mode_e mode = get_preprocessing_allow_mode(current_maclient_appid);
-
- switch (event) {
- case PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED:
- {
-#ifndef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
- /* If there is no need to bring preprocessing assistant to front,
- current_maclient should always be brought to front */
- mas_bring_client_to_foreground(current_maclient_appid);
-#endif
- g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
- if (check_preprocessing_assistant_exists()) {
- if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
- MA_PREPROCESSING_ALLOW_ALL == mode) {
- if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
- g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
- }
- }
- } else {
-#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
- /* If preprocessing assistant does not exist, there is no way to enable
- preprocessing assistant, so bring current maclient to front right away */
- mas_bring_client_to_foreground(current_maclient_appid);
-#endif
- }
- }
- break;
- case PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED:
- {
- g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
- /* Enable preprocessing mode only if the preprocessing assistant exists */
- if (check_preprocessing_assistant_exists()) {
- if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
- MA_PREPROCESSING_ALLOW_ALL == mode) {
- if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
- g_current_preprocessing_state = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
- }
- }
- }
- }
- break;
- case PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED:
- {
- if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED == g_current_preprocessing_state) {
- g_current_preprocessing_state = PREPROCESSING_STATE_PREPROCESSING_UTTERANCE;
- } else if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED == g_current_preprocessing_state) {
- /* If preprocessing assistant does not exist, the current_maclient
- would have been brought to front already on wakeup event */
-#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
- if (check_preprocessing_assistant_exists()) {
- mas_bring_client_to_foreground(current_maclient_appid);
- }
-#endif
- g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
- }
- }
- break;
- case PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED:
- {
- g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
- if (check_preprocessing_assistant_exists()) {
- if (MA_PREPROCESSING_ALLOW_FOLLOW_UP == mode ||
- MA_PREPROCESSING_ALLOW_ALL == mode) {
- g_current_preprocessing_state = PREPROCESSING_STATE_PREPROCESSING_FOLLOW_UP;
- }
- }
- }
- break;
- case PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED:
- {
-#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
- if (PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED == g_current_preprocessing_state ||
- PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED == g_current_preprocessing_state) {
- char* vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
- MAS_LOGD("preprocessing_assistant_appid : %s", vconf_str);
- if (vconf_str) {
- mas_bring_client_to_foreground(vconf_str);
- free(vconf_str);
- vconf_str = NULL;
- }
- }
-#endif
- g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
- }
- break;
- case PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED:
- {
-#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
- if (PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED == g_current_preprocessing_state ||
- PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED == g_current_preprocessing_state) {
- mas_bring_client_to_foreground(current_maclient_appid);
- }
-#endif
- g_current_preprocessing_state = PREPROCESSING_STATE_NONE;
- }
- break;
- }
- return 0;
-}
-
-int mas_set_current_service_state(ma_service_state_e state)
-{
- g_current_service_state = state;
-
- ma_client_s *data = NULL;
-
- int count = g_slist_length(g_client_list);
- int i;
-
- for (i = 0; i < count; i++) {
- data = g_slist_nth_data(g_client_list, i);
-
- if (NULL != data && -1 != data->pid) {
- int ret = masc_dbus_service_state_change(data->pid, state);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send wakeup service state change to %d, ret(%d)",
- data->pid, ret);
- }
- }
- }
- return 0;
-}
-
-ma_service_state_e mas_get_current_service_state()
-{
- return g_current_service_state;
-}
-
-static int pkg_app_list_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
-{
- char *appid = NULL;
-
- int ret = pkgmgrinfo_appinfo_get_appid (handle, &appid);
- if (PMINFO_R_OK == ret && NULL != appid) {
- int *result = (int*)user_data;
- if (result) {
- for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM;loop++) {
- if (g_maclient_info[loop].used) {
- LOGD("comparing appid : %s %s", g_maclient_info[loop].wakeup_engine, appid);
- if (0 == strncmp(g_maclient_info[loop].wakeup_engine, appid, MAX_APPID_LEN)) {
- *result = 1;
- }
- }
- }
- }
- } else {
- LOGE("pkgmgrinfo_appinfo_get_appid failed! error code=%d", ret);
- return 0;
- }
-
- return 0;
-}
-
-/*
-INFO: Package install/update/uninstall scenario
-Install and Uninstall are obviously simple.
- Install: just INSTALL
- Uninstall: just UNINSTALL
-Update package (change the source codes and Run As again), there are four scenarios:
-1. UPDATE
- Source code change
-2. UNINSTALL -> INSTALL
- This happens when Tizen IDE Property > Tizen SDK > Rapid Development Support > Check "Enable Project specific settings"
- and change Application ID in tizen-manifest.xml file and Run As.
-3. UPDATE -> INSTALL
- This happens when Tizen IDE Property > Tizen SDK > Rapid Development Support > Uncheck "Enable Project specific settings"
- and change Application ID in tizen-manifest.xml file and Run As.
- At UPDATE event, pkgid (package parameter) is invalid...
-4. UPDATE
- Exceptionally, only UPDATE can be called when Application ID in tizen-manifest.xml file is changed.
- At UPDATE event, pkgid (package parameter) is valid, and only appid is changed; the previous appid is invalid.
-*/
-static void _package_manager_event_cb(const char *type, const char *package, package_manager_event_type_e event_type, package_manager_event_state_e event_state, int progress, package_manager_error_e error, void *user_data)
-{
- int ret = 0;
- uid_t uid = getuid ();
- pkgmgrinfo_pkginfo_h handle = NULL;
- static bool in_progress = false;
- bool should_exit = false;
-
- if (!package || !type)
- return;
-
- if (PACKAGE_MANAGER_EVENT_TYPE_UPDATE != event_type &&
- PACKAGE_MANAGER_EVENT_TYPE_INSTALL != event_type &&
- PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL != event_type)
- return;
-
- if (PACKAGE_MANAGER_EVENT_STATE_STARTED != event_state &&
- PACKAGE_MANAGER_EVENT_STATE_COMPLETED != event_state)
- return;
-
- bool user = false;
- LOGD("type=%s package=%s event_type=%d event_state=%d progress=%d error=%d",
- type, package, event_type, event_state, progress, error);
- ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle);
- if (ret != PMINFO_R_OK || NULL == handle) {
- LOGW("Failed to call pkgmgrinfo_pkginfo_get_pkginfo & get_usr_pkginfo(\"%s\",~) returned %d, uid : %d", package, ret, getuid ());
- /* Try to get in user packages */
- user = true;
- ret = pkgmgrinfo_pkginfo_get_usr_pkginfo (package, uid, &handle);
- if (ret != PMINFO_R_OK || NULL == handle) {
- LOGW("Failed to call pkgmgrinfo_pkginfo_get_pkginfo & get_usr_pkginfo(\"%s\",~) returned %d, uid : %d", package, ret, getuid ());
- return;
- }
- }
-
- if (user) {
- /* Try to get in user packages */
- pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, pkg_app_list_cb, (void *)&ret, uid);
- } else {
- /* Try to get in global packages */
- pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP, pkg_app_list_cb, (void *)&ret);
- }
- if (1 == ret) {
- if (PACKAGE_MANAGER_EVENT_STATE_STARTED == event_state) {
- LOGI("processing PACKAGE_MANAGER_EVENT_STATE_STARTED event : %d", event_type);
- if (false == in_progress) {
- in_progress = true;
- deinit_plugin();
- }
- } else if (PACKAGE_MANAGER_EVENT_STATE_COMPLETED == event_state) {
- LOGI("processing PACKAGE_MANAGER_EVENT_STATE_COMPLETED event : %d", event_type);
- if (false == in_progress) {
- deinit_plugin();
- }
- should_exit = true;
- in_progress = false;
- }
- }
-
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-
- if (should_exit) {
- LOGI("Now restarting multi-assistant-service for reloading updated modules");
- service_app_exit();
- }
-
- return;
-}
-
-bool service_app_create(void *data)
-{
- // Todo: add your code here.
-
- MAS_LOGD("[Enter] Service app create");
-
- if (0 != init_wakeup()) {
- MAS_LOGE("Fail to init wakeup service");
- return false;
- }
-
- if (!g_pkgmgr) {
- int ret = package_manager_create(&g_pkgmgr);
- if (ret == PACKAGE_MANAGER_ERROR_NONE) {
- ret = package_manager_set_event_cb(g_pkgmgr, _package_manager_event_cb, NULL);
- if (ret == PACKAGE_MANAGER_ERROR_NONE) {
- LOGD("package_manager_set_event_cb succeeded.");
- }
- else {
- LOGE("package_manager_set_event_cb failed(%d)", ret);
- }
- }
- else {
- LOGE("package_manager_create failed(%d)", ret);
- }
- }
-
- return true;
-}
-
-void service_app_terminate(void *data)
-{
- MAS_LOGI("[ENTER]");
- if (g_pkgmgr) {
- package_manager_unset_event_cb(g_pkgmgr);
- package_manager_destroy(g_pkgmgr);
- g_pkgmgr = NULL;
- }
-
- // Todo: add your code here.
- deinit_wakeup();
- MAS_LOGI("[END]");
- return;
-}
-
-void service_app_control(app_control_h app_control, void *data)
-{
- // Todo: add your code here.
- return;
-}
-
-static void
-service_app_lang_changed(app_event_info_h event_info, void *user_data)
-{
- /*APP_EVENT_LANGUAGE_CHANGED*/
- return;
-}
-
-static void
-service_app_region_changed(app_event_info_h event_info, void *user_data)
-{
- /*APP_EVENT_REGION_FORMAT_CHANGED*/
-}
-
-static void
-service_app_low_battery(app_event_info_h event_info, void *user_data)
-{
- /*APP_EVENT_LOW_BATTERY*/
-}
-
-static void
-service_app_low_memory(app_event_info_h event_info, void *user_data)
-{
- /*APP_EVENT_LOW_MEMORY*/
-}
-
-int main(int argc, char* argv[])
-{
- char ad[50] = {0,};
- service_app_lifecycle_callback_s event_callback;
- app_event_handler_h handlers[5] = {NULL, };
-
- event_callback.create = service_app_create;
- event_callback.terminate = service_app_terminate;
- event_callback.app_control = service_app_control;
-
- service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
- service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
- service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
- service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
-
- int ret = service_app_main(argc, argv, &event_callback, ad);
- LOGI("Main function exits with : %d", ret);
- return ret;
-}
+++ /dev/null
-/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <tizen.h>
-#include <service_app.h>
-#include <app_manager.h>
-#include <app.h>
-#include <malloc.h>
-#include <Ecore.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <dlfcn.h>
-
-#include "multi_wakeup_recognizer.h"
-#include "multi_assistant_main.h"
-#include "multi_assistant_service_client.h"
-#include "multi_assistant_service_plugin.h"
-#include "multi_assistant_dbus.h"
-
-/* Sound buf save for test */
-#if 0
-#define BUF_SAVE_MODE
-#endif
-
-#ifdef BUF_SAVE_MODE
-static char g_temp_file_name[128] = {'\0',};
-
-static FILE* g_pFile = NULL;
-
-static int g_count = 1;
-#endif
-
-static void *g_handle = NULL;
-
-static wakeup_manager_interface _wakeup_manager_interface = { NULL, };
-static ma_plugin_settings* g_plugin_settings = NULL;
-
-static bool is_ui_panel_enabled()
-{
- /* By default we assume the ui panel is always enabled unless explicitly turned off */
- bool ret = true;
- if (g_plugin_settings) {
- ret = g_plugin_settings->ui_panel_enabled;
- }
- MAS_LOGD("UI Panel Enabled : %d", ret);
- return ret;
-}
-
-#if 0 /* + TEST_CODE */
-Eina_Bool __send_asr_result(void *data)
-{
- MAS_LOGD("[ENTER]");
-
- if (!strcmp((char*)data, "Today's")) {
- masc_ui_dbus_send_asr_result(-1, 1, "Today's");
- }
- if (!strcmp((char*)data, "weather.")) {
- masc_ui_dbus_send_asr_result(-1, 0, "Today's weather.");
- }
-
- MAS_LOGD("END");
- return EINA_FALSE;
-}
-
-Eina_Bool __send_result(void *data)
-{
- MAS_LOGD("[ENTER]");
-
- int ret = masc_ui_dbus_send_result(-1, (const char*)data, (const char*)data, "test");
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to stop recording(%d)", ret);
- return EINA_TRUE;
- }
-
- MAS_LOGD("END");
- return EINA_FALSE;
-}
-#endif /* -TEST_CODE */
-
-Eina_Bool process_wakeup_event_by_appid_timer(char* appid)
-{
- MAS_LOGD("[ENTER] appid(%s)", appid);
-
- int pid = -1;
- if (!appid) return ECORE_CALLBACK_CANCEL;
-
- bool use_custom_ui = mas_get_client_custom_ui_option_by_appid(appid);
- bool ui_panel_enabled = is_ui_panel_enabled();
- if (ui_panel_enabled) masc_ui_dbus_enable_common_ui(!use_custom_ui);
-
- mas_set_current_client_by_appid(appid);
- if (ui_panel_enabled) masc_ui_dbus_change_assistant(appid);
- if ((pid = mas_get_client_pid_by_appid(appid)) != -1) {
- mas_client_send_preprocessing_information(pid);
- mas_client_activate(pid);
- mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
- } else {
- // Appropriate MA Client not available, trying to launch new one
- MAS_LOGD("MA Client with appid %s does not exist, launching client", appid);
- mas_launch_client_by_appid(appid, CLIENT_LAUNCH_MODE_ACTIVATION);
- }
-
- if (appid) free(appid);
-
- MAS_LOGD("END");
- return ECORE_CALLBACK_CANCEL;
-}
-
-Eina_Bool process_wakeup_event_by_word_timer(char* wakeup_word)
-{
- MAS_LOGD("[ENTER]");
-
- if (!wakeup_word) return EINA_FALSE;
-
- const char* appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
- process_wakeup_event_by_appid_timer(strdup(appid));
-
- if (wakeup_word) free(wakeup_word);
-
- MAS_LOGD("END");
- return ECORE_CALLBACK_CANCEL;
-}
-
-static void __wakeup_event_cb(mas_wakeup_event_info wakeup_info, void* user_data)
-{
- MAS_LOGD("[SUCCESS] __wakeup_event_cb is called, wakeup_word(%s)", wakeup_info.wakeup_word);
- int ret = -1;
-
- if (is_ui_panel_enabled()) {
- int retry_cnt = 0;
- while (0 != ret) {
- ret = masc_ui_dbus_send_hello();
- retry_cnt++;
- if (5 < retry_cnt) {
- MAS_LOGE("[ERROR] Fail to receive reply for hello, ret(%d)", ret);
- break;
- }
- }
- }
-
-#ifdef BUF_SAVE_MODE
- if (g_pFile) {
- fclose(g_pFile);
- g_pFile = NULL;
- } else {
- MAS_LOGD("[Recorder Info] File not found!");
- }
-
- while (1) {
- snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/ma_service_%d_%d", getpid(), g_count);
- int ret = access(g_temp_file_name, 0);
-
- if (0 == ret) {
- MAS_LOGD("[Recorder ERROR] File is already exist");
- if (0 == remove(g_temp_file_name)) {
- MAS_LOGD("[Recorder] Remove file");
- break;
- } else {
- g_count++;
- }
- } else {
- break;
- }
- }
-
- MAS_LOGD("[Recorder] Temp file name=[%s]", g_temp_file_name);
-
- /* open test file */
- g_pFile = fopen(g_temp_file_name, "wb+x");
- if (!g_pFile) {
- MAS_LOGD("[Recorder ERROR] File not found!");
- return;
- }
- g_count++;
-#endif
-
-#if 0 /* + TEST_CODE */
- if (WAKEUP_EVENT_SUCCESS == event) {
- ecore_thread_main_loop_begin();
- ecore_timer_add(1.0, __send_asr_result, "Today's");
- ecore_thread_main_loop_end();
-
- ecore_thread_main_loop_begin();
- ecore_timer_add(2.0, __send_asr_result, "weather.");
- ecore_thread_main_loop_end();
-
- ecore_thread_main_loop_begin();
- ecore_timer_add(3.0, __send_result, "Partly cloudy with temperatures from 75 to 88");
- ecore_thread_main_loop_end();
- }
-#endif /* - TEST_CODE */
- if (wakeup_info.wakeup_appid) {
- ecore_thread_main_loop_begin();
- ecore_timer_add(0.0f, process_wakeup_event_by_appid_timer, (void*)strdup(wakeup_info.wakeup_appid));
- ecore_thread_main_loop_end();
- } else if (wakeup_info.wakeup_word) {
- ecore_thread_main_loop_begin();
- ecore_timer_add(0.0f, process_wakeup_event_by_word_timer, (void*)strdup(wakeup_info.wakeup_word));
- ecore_thread_main_loop_end();
- }
-
-}
-
-static bool __validate_streaming_event_order(int pid, mas_speech_streaming_event_e *event)
-{
- bool ret = false;
-
- static int previous_pid = -1;
- static mas_speech_streaming_event_e previous_event = MAS_SPEECH_STREAMING_EVENT_FINISH;
-
- if (NULL == event) return false;
-
- mas_speech_streaming_event_e expected_sequence [][2] = {
- {MAS_SPEECH_STREAMING_EVENT_START, MAS_SPEECH_STREAMING_EVENT_CONTINUE},
- {MAS_SPEECH_STREAMING_EVENT_START, MAS_SPEECH_STREAMING_EVENT_FINISH},
- {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) {
- /* When sending streaming event to a new client, it always sends START message first */
- previous_event = MAS_SPEECH_STREAMING_EVENT_FINISH;
- }
-
- for (int loop = 0;loop < sizeof(expected_sequence) / sizeof(expected_sequence[0]);loop++) {
- if (previous_event == expected_sequence[loop][0] &&
- *event == expected_sequence[loop][1]) {
- ret = true;
- }
- }
- if (!ret) {
- /* In case of FINISH -> CONTINUE without START, simply modify current event value */
- if (MAS_SPEECH_STREAMING_EVENT_FINISH == previous_event &&
- MAS_SPEECH_STREAMING_EVENT_CONTINUE == *event) {
- *event = MAS_SPEECH_STREAMING_EVENT_START;
- ret = true;
-
- MAS_LOGD("[WARNING] forcibly changed CONTINUE to START : %d -> %d (PID %d -> %d)",
- previous_event, *event, previous_pid, pid);
- }
- }
-
- if (ret) {
- previous_pid = pid;
- previous_event = *event;
- } else {
- MAS_LOGE("[ERROR] State sequence validation failed : %d -> %d (PID %d -> %d)",
- previous_event, *event, previous_pid, pid);
- }
- return ret;
-}
-
-static void handle_speech_streaming_event_failure(void *data)
-{
- mas_client_send_recognition_result(0, MA_RECOGNITION_RESULT_EVENT_ERROR);
-}
-
-static void __audio_streaming_cb(mas_speech_streaming_event_e event, unsigned char* buffer, int len, void *user_data)
-{
- if (event == MAS_SPEECH_STREAMING_EVENT_FAIL) {
- ecore_main_loop_thread_safe_call_async(handle_speech_streaming_event_failure, NULL);
- return;
- }
- static int count = 0;
- if (event != MAS_SPEECH_STREAMING_EVENT_CONTINUE || count % 100 == 0) {
- MAS_LOGD( "[SUCCESS] __audio_streaming_cb is called, event(%d), buffer(%p), len(%d)", event, buffer, len);
- }
- ++count;
-
- int pid = mas_get_current_client_pid();
- int preprocessing_pid = mas_get_current_preprocessing_client_pid();
- if (pid == -1) {
- MAS_LOGE("[ERROR] Fail to retrieve pid of current MA client");
- } else {
- if (__validate_streaming_event_order(pid, &event)) {
- int ret = masc_dbus_send_streaming_audio_data(pid, event, buffer, len);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send speech data, ret(%d)", ret);
- }
- if (pid != preprocessing_pid && -1 != preprocessing_pid) {
- int ret = masc_dbus_send_streaming_audio_data(preprocessing_pid, event, buffer, len);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send speech data to preprocessing client, ret(%d)", ret);
- }
- }
- }
- }
-
-#ifdef BUF_SAVE_MODE
- /* write pcm buffer */
- if (g_pFile)
- fwrite(buffer, 1, len, g_pFile);
-
- if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
- if (g_pFile) {
- MAS_LOGE("[Recorder SUCCESS] File Close");
- fclose(g_pFile);
- g_pFile = NULL;
- } else {
- MAS_LOGE("[Recorder ERROR] File not found!");
- }
- }
-#endif
-}
-
-static void __speech_status_cb(mas_speech_status_e status, void *user_data)
-{
- MAS_LOGD( "[SUCCESS] __speech_status_cb is called, status(%d)", status);
-}
-
-static void __error_cb(int error, const char* err_msg, void* user_data)
-{
- MAS_LOGD( "[SUCCESS] __error_cb is called, error(%d), err_msg(%s)", error, err_msg);
-
- if (is_ui_panel_enabled()) {
- int ret = masc_ui_dbus_send_error_message(error, err_msg);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send error message, ret(%d)", ret);
- }
- }
-}
-
-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");
-}
-
-static void __streaming_section_changed_cb(ma_audio_streaming_data_section_e section, void* user_data)
-{
- MAS_LOGD( "[SUCCESS] __streaming_section_changed_cb is called, section(%d)", section);
-
- int pid = mas_get_current_client_pid();
- int ret = masc_dbus_send_streaming_section_changed(pid, (int)section);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send streaming section changed information, ret(%d)", ret);
- }
-}
-
-static void __wakeup_engine_command_cb(mas_wakeup_engine_command_target_e target, const char* assistant_name, const char* command, void* user_data)
-{
- MAS_LOGD( "[SUCCESS] __wakeup_engine_command_cb is called, command(%s)", command);
-
- int pid = mas_get_client_pid_by_appid(assistant_name);
- if (-1 != pid) {
- int ret = masc_dbus_send_wakeup_engine_command(pid, command);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to send wakeup engine command, ret(%d)", ret);
- }
- }
-}
-
-static void __wakeup_service_state_changed_cb(ma_service_state_e state, void* user_data)
-{
- MAS_LOGD( "[SUCCESS] __wakeup_service_state_changed_cb is called, state(%d)", state);
-
- 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]");
-
- char filepath[512] = {'\0',};
- const char *default_engine_path = MA_WAKEUP_MANAGER_PATH;
- snprintf(filepath, 512, "%s/%s", default_engine_path, MA_DEFAULT_WAKEUP_MANAGER_FILENAME);
-
- char *error;
- g_handle = NULL;
- g_handle = dlopen(filepath, RTLD_LAZY);
- if (NULL != (error = dlerror())) {
- MAS_LOGE("[ERROR] Fail to dlopen(%s), error(%s)", filepath, error);
- return -1; //MAS_ERROR_OPERATION_FAILED;
- }
-
- _wakeup_manager_interface.initialize =
- (wakeup_manager_initialize)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_INITIALIZE);
- _wakeup_manager_interface.deinitialize =
- (wakeup_manager_deinitialize)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE);
- _wakeup_manager_interface.get_settings =
- (wakeup_manager_get_settings)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
- _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.add_assistant_language =
- (wakeup_manager_add_assistant_language)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE);
- _wakeup_manager_interface.set_assistant_wakeup_engine =
- (wakeup_manager_set_assistant_wakeup_engine)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_WAKEUP_ENGINE);
- _wakeup_manager_interface.set_default_assistant =
- (wakeup_manager_set_default_assistant)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_DEFAULT_ASSISTANT);
- _wakeup_manager_interface.get_default_assistant =
- (wakeup_manager_get_default_assistant)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_GET_DEFAULT_ASSISTANT);
- _wakeup_manager_interface.set_language =
- (wakeup_manager_set_language)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE);
- _wakeup_manager_interface.activate =
- (wakeup_manager_activate)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_ACTIVATE);
- _wakeup_manager_interface.deactivate =
- (wakeup_manager_deactivate)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_DEACTIVATE);
- _wakeup_manager_interface.update_voice_feedback_state =
- (wakeup_manager_update_voice_feedback_state)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE);
- _wakeup_manager_interface.set_assistant_specific_command =
- (wakeup_manager_set_assistant_specific_command)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_SPECIFIC_COMMAND);
- _wakeup_manager_interface.set_background_volume =
- (wakeup_manager_set_background_volume)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_BACKGROUND_VOLUME);
- _wakeup_manager_interface.update_recognition_result =
- (wakeup_manager_update_recognition_result)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_UPDATE_RECOGNITION_RESULT);
- _wakeup_manager_interface.process_plugin_event =
- (wakeup_manager_process_plugin_event)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_PROCESS_PLUGIN_EVENT);
- _wakeup_manager_interface.start_streaming_utterance_data =
- (wakeup_manager_start_streaming_utterance_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA);
- _wakeup_manager_interface.stop_streaming_utterance_data =
- (wakeup_manager_stop_streaming_utterance_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA);
- _wakeup_manager_interface.start_streaming_previous_utterance_data =
- (wakeup_manager_start_streaming_previous_utterance_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA);
- _wakeup_manager_interface.stop_streaming_previous_utterance_data =
- (wakeup_manager_stop_streaming_previous_utterance_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA);
- _wakeup_manager_interface.start_streaming_follow_up_data =
- (wakeup_manager_start_streaming_follow_up_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA);
- _wakeup_manager_interface.stop_streaming_follow_up_data =
- (wakeup_manager_stop_streaming_follow_up_data)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA);
- _wakeup_manager_interface.get_audio_format =
- (wakeup_manager_get_audio_format)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT);
- _wakeup_manager_interface.get_audio_source_type =
- (wakeup_manager_get_audio_source_type)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_SOURCE_TYPE);
- _wakeup_manager_interface.set_wake_word_audio_require_flag =
- (wakeup_manager_set_wake_word_audio_require_flag)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG);
- _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);
- _wakeup_manager_interface.set_utterance_streaming_callback =
- (wakeup_manager_set_utterance_streaming_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK);
- _wakeup_manager_interface.set_previous_utterance_streaming_callback =
- (wakeup_manager_set_previous_utterance_streaming_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK);
- _wakeup_manager_interface.set_follow_up_streaming_callback =
- (wakeup_manager_set_follow_up_streaming_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK);
- _wakeup_manager_interface.set_speech_status_callback =
- (wakeup_manager_set_speech_status_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK);
- _wakeup_manager_interface.set_setting_changed_callback =
- (wakeup_manager_set_setting_changed_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_SETTING_CHANGED_CALLBACK);
- _wakeup_manager_interface.set_error_callback =
- (wakeup_manager_set_error_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK);
- _wakeup_manager_interface.set_streaming_section_changed_callback =
- (wakeup_manager_set_streaming_section_changed_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_STREAMING_SECTION_CHANGED_CALLBACK);
- _wakeup_manager_interface.set_wakeup_engine_command_callback =
- (wakeup_manager_set_wakeup_engine_command_callback)dlsym(g_handle,
- MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_ENGINE_COMMAND_CALLBACK);
- _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) {
- wakeup_manager_initialize func = _wakeup_manager_interface.initialize;
-
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_INITIALIZE);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to initialize, ret(%d)", ret);
- }
- }
-
- wakeup_manager_get_settings get_settings_func = _wakeup_manager_interface.get_settings;
-
- if (NULL == get_settings_func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
- } else {
- size_t struct_size;
- ret = get_settings_func(&g_plugin_settings, &struct_size);
- if (0 != ret || struct_size != sizeof(ma_plugin_settings)) {
- MAS_LOGE("[ERROR] Fail to get settings, ret(%d), size %zu", ret, struct_size);
- g_plugin_settings = NULL;
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_deinitialize(void)
-{
-#ifdef BUF_SAVE_MODE
- if (g_pFile) {
- fclose(g_pFile);
- g_pFile = NULL;
- } else {
- MAS_LOGD("[Recorder ERROR] File not found!");
- }
-#endif
-
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_deinitialize func = _wakeup_manager_interface.deinitialize;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to deinitialize, ret(%d)", ret);
- }
- }
-
- dlclose(g_handle);
- g_handle = NULL;
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
-
- return ret;
-}
-
-int multi_assistant_service_plugin_get_settings(ma_plugin_settings **settings, size_t *struct_size)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_get_settings func = _wakeup_manager_interface.get_settings;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
- } else {
- ret = func(settings, struct_size);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to get settings, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_language(const char* language)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_language func = _wakeup_manager_interface.set_language;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE);
- } else {
- ret = func(language);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set langauge(%s), ret(%d)", language, ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_add_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_add_assistant_wakeup_word func = _wakeup_manager_interface.add_assistant_wakeup_word;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_WAKEUP_WORD);
- } 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);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_add_assistant_language(const char* appid, const char* language)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_add_assistant_language func = _wakeup_manager_interface.add_assistant_language;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE);
- } else {
- ret = func(appid, language);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set wakeup word(%s)(%s), ret(%d)", appid, language, ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_assistant_wakeup_engine(const char* appid, const char* engine)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_assistant_wakeup_engine func = _wakeup_manager_interface.set_assistant_wakeup_engine;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_WAKEUP_ENGINE);
- } else {
- ret = func(appid, engine);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set wakeup engine(%s)(%s), ret(%d)", appid, engine, ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_default_assistant(const char* appid)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_default_assistant func = _wakeup_manager_interface.set_default_assistant;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_DEFAULT_ASSISTANT);
- } else {
- ret = func(appid);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set default assistant(%s), ret(%d)", appid, ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_get_default_assistant(const char** appid)
-{
- int ret = -1;
- if (NULL == appid) {
- MAS_LOGE("[ERROR] appid is not valid");
- return ret;
- }
- if (NULL != g_handle) {
- wakeup_manager_get_default_assistant func = _wakeup_manager_interface.get_default_assistant;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_DEFAULT_ASSISTANT);
- } else {
- ret = func(appid);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to get default assistant, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_activate(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_activate func = _wakeup_manager_interface.activate;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ACTIVATE);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to start recording, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_deactivate(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_deactivate func = _wakeup_manager_interface.deactivate;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEACTIVATE);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_update_voice_feedback_state(const char* appid, int state)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_update_voice_feedback_state func = _wakeup_manager_interface.update_voice_feedback_state;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE);
- } else {
- ret = func(appid, state);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_assistant_specific_command(const char* appid, const char* command)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_assistant_specific_command func = _wakeup_manager_interface.set_assistant_specific_command;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_SPECIFIC_COMMAND);
- } else {
- ret = func(appid, command);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_background_volume(const char* appid, double ratio)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_background_volume func = _wakeup_manager_interface.set_background_volume;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_BACKGROUND_VOLUME);
- } else {
- ret = func(appid, ratio);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set background volume, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_update_recognition_result(const char* appid, int state)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_update_recognition_result func = _wakeup_manager_interface.update_recognition_result;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_RECOGNITION_RESULT);
- } else {
- ret = func(appid, state);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to update result state, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_process_event(int event, void *data, int len)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_process_plugin_event func = _wakeup_manager_interface.process_plugin_event;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_PROCESS_PLUGIN_EVENT);
- } else {
- ret = func((mas_plugin_event_e)event, data, len);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_start_streaming_utterance_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_start_streaming_utterance_data func = _wakeup_manager_interface.start_streaming_utterance_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_stop_streaming_utterance_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_stop_streaming_utterance_data func = _wakeup_manager_interface.stop_streaming_utterance_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_start_streaming_previous_utterance_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_start_streaming_previous_utterance_data func = _wakeup_manager_interface.start_streaming_previous_utterance_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request previous speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_stop_streaming_previous_utterance_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_stop_streaming_previous_utterance_data func = _wakeup_manager_interface.stop_streaming_previous_utterance_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request previous speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_start_streaming_follow_up_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_start_streaming_follow_up_data func = _wakeup_manager_interface.start_streaming_follow_up_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_stop_streaming_follow_up_data(void)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_stop_streaming_follow_up_data func = _wakeup_manager_interface.stop_streaming_follow_up_data;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA);
- } else {
- ret = func();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_get_recording_audio_format(int *rate, int *channel, int *audio_type)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_get_audio_format func = _wakeup_manager_interface.get_audio_format;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT);
- } else {
- ret = func(rate, channel, audio_type);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_get_recording_audio_source_type(char** type)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_get_audio_source_type func = _wakeup_manager_interface.get_audio_source_type;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_SOURCE_TYPE);
- } else {
- ret = func(type);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to get recording audio source type, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- 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;
- if (NULL != g_handle) {
- wakeup_manager_set_wake_word_audio_require_flag func = _wakeup_manager_interface.set_wake_word_audio_require_flag;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG);
- } else {
- ret = func(require);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set wake word audio require flag, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_assistant_language(const char* appid, const char* language)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_assistant_language func = _wakeup_manager_interface.set_assistant_language;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_LANGUAGE);
- } else {
- ret = func(appid, language);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set assistant language, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_callbacks(void)
-{
- int ret = multi_assistant_service_plugin_set_wakeup_event_callback(__wakeup_event_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set wakeup event cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_utterance_streaming_callback(__audio_streaming_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set utterance streaming cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_previous_utterance_streaming_callback(__audio_streaming_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set previous utterance streaming cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_follow_up_streaming_callback(__audio_streaming_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set follow-up streaming cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_speech_status_callback(__speech_status_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set speech status changed cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_setting_changed_callback(__setting_changed_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set setting changed cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_error_callback(__error_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set error cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_streaming_section_changed_callback(__streaming_section_changed_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set streaming section changed cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_wakeup_engine_command_callback(__wakeup_engine_command_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set wakeup engine command cb");
- return ret;
- }
-
- ret = multi_assistant_service_plugin_set_wakeup_service_state_changed_callback(__wakeup_service_state_changed_cb, NULL);
- if (0 != ret) {
- MAS_LOGE("Fail to set wakeup engine command cb");
- 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;
-}
-
-int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_wakeup_event_callback func = _wakeup_manager_interface.set_wakeup_event_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set wakeup event callback, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_utterance_streaming_callback func = _wakeup_manager_interface.set_utterance_streaming_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_previous_utterance_streaming_callback func = _wakeup_manager_interface.set_previous_utterance_streaming_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_follow_up_streaming_callback func = _wakeup_manager_interface.set_follow_up_streaming_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set follow-up streaming callback, ret(%d)", ret);
- }
- }
- } else {
- MAS_LOGE("[ERROR] g_handle is not valid");
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_speech_status_callback func = _wakeup_manager_interface.set_speech_status_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set speech status callback, ret(%d)", ret);
- }
- }
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_setting_changed_callback(wakeup_service_setting_changed_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_setting_changed_callback func = _wakeup_manager_interface.set_setting_changed_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_SETTING_CHANGED_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set setting_changed callback, ret(%d)", ret);
- }
- }
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_error_callback(wakeup_service_error_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_error_callback func = _wakeup_manager_interface.set_error_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
- }
- }
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_streaming_section_changed_callback(wakeup_service_streaming_section_changed_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_streaming_section_changed_callback func = _wakeup_manager_interface.set_streaming_section_changed_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_STREAMING_SECTION_CHANGED_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set streaming section changed callback, ret(%d)", ret);
- }
- }
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_wakeup_engine_command_callback(wakeup_service_wakeup_engine_command_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_wakeup_engine_command_callback func = _wakeup_manager_interface.set_wakeup_engine_command_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_ENGINE_COMMAND_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
- }
- }
- }
- return ret;
-}
-
-int multi_assistant_service_plugin_set_wakeup_service_state_changed_callback(wakeup_service_wakeup_service_state_changed_cb callback, void* user_data)
-{
- int ret = -1;
- if (NULL != g_handle) {
- wakeup_manager_set_wakeup_service_state_changed_callback func = _wakeup_manager_interface.set_wakeup_service_state_changed_callback;
- if (NULL == func) {
- MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_SERVICE_STATE_CHANGED_CALLBACK);
- } else {
- ret = func(callback, user_data);
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
- }
- }
- }
- 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;
-}
-
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "preference_manager_vconf.h"
+
+#include <vconf.h>
+
+CPreferenceManagerVconf::CPreferenceManagerVconf()
+{
+}
+
+CPreferenceManagerVconf::~CPreferenceManagerVconf()
+{
+}
+
+boost::optional<std::string> CPreferenceManagerVconf::get_string(const std::string& key)
+{
+ boost::optional<std::string> ret;
+
+ char* vconf_str = vconf_get_str(key.c_str());
+ if (vconf_str) {
+ ret = std::string{vconf_str};
+ free(vconf_str);
+ vconf_str = NULL;
+ }
+
+ return ret;
+}
+
+boost::optional<int> CPreferenceManagerVconf::get_int(const std::string& key)
+{
+ boost::optional<int> ret;
+
+ int vconf_value = 0;
+ int succeeded = vconf_get_int(key.c_str(), &vconf_value);
+ if (0 == succeeded) {
+ ret = vconf_value;
+ }
+
+ return ret;
+}
+
+boost::optional<bool> CPreferenceManagerVconf::get_bool(const std::string& key)
+{
+ boost::optional<bool> ret;
+
+ int vconf_value = 0;
+ int succeeded = vconf_get_bool(key.c_str(), &vconf_value);
+ if (0 == succeeded) {
+ /* Non-zero means true */
+ ret = (vconf_value != 0);
+ }
+
+ return ret;
+}
+
+static void vconf_key_changed(keynode_t* key, void* data)
+{
+ if (nullptr == key) return;
+
+ const char* name = vconf_keynode_get_name(key);
+ if (nullptr == name) return;
+
+ CPreferenceManagerVconf* preference_manager =
+ static_cast<CPreferenceManagerVconf*>(data);
+ if (nullptr == preference_manager) return;
+
+ const std::map<std::string, std::list<CallbackEntry>>& entries_map =
+ preference_manager->get_callbacks();
+
+ std::map<std::string, std::list<CallbackEntry>>::const_iterator iter =
+ entries_map.find(name);
+
+ if (iter != entries_map.end()) {
+ std::list<CallbackEntry> entries = iter->second;
+ /* Iterate through list */
+ for (const auto& entry : entries) {
+ preference_changed_cb callback = std::get<0>(entry);
+ void* user_data = std::get<1>(entry);
+ callback(std::string{name}, user_data);
+ }
+ }
+}
+
+bool CPreferenceManagerVconf::register_changed_callback(
+ const std::string& key, preference_changed_cb callback, void* user_data)
+{
+ bool ret = false;
+
+ std::list<CallbackEntry> entries;
+ CallbackEntry entry = std::make_tuple(callback, user_data);
+ std::map<std::string, std::list<CallbackEntry>>::iterator iter =
+ mCallbackEntries.find(key);
+
+ bool registered = false;
+ if (iter != mCallbackEntries.end()) {
+ entries = iter->second;
+ registered = true;
+ }
+
+ /* Avoid registering vconf_key_changed() for the same key */
+ if (!registered) {
+ if (0 == vconf_notify_key_changed(key.c_str(), vconf_key_changed, this)) {
+ registered = true;
+ }
+ }
+ if (registered) {
+ entries.push_back(entry);
+ mCallbackEntries[key] = entries;
+ ret = true;
+ }
+ return ret;
+}
+
+bool CPreferenceManagerVconf::unregister_changed_callback(const std::string& key, preference_changed_cb callback)
+{
+ std::map<std::string, std::list<CallbackEntry>>::iterator map_iter =
+ mCallbackEntries.find(key);
+
+ if (map_iter != mCallbackEntries.end()) {
+ bool found = false;
+ for (const auto& entry : map_iter->second) {
+ if (callback == std::get<0>(entry)) {
+ if (!found) {
+ map_iter->second.remove(entry);
+ found = true;
+ }
+ }
+ }
+ if (map_iter->second.empty()) {
+ vconf_ignore_key_changed(key.c_str(), vconf_key_changed);
+ }
+ }
+ return true;
+}
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libxml/parser.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <app_preference.h>
+
+#include "service_config.h"
+#include "service_common.h"
+
+int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callback,
+ const char *path, void* user_data)
+{
+ xmlDocPtr doc = NULL;
+ xmlNodePtr cur = NULL;
+ xmlChar *key;
+
+ int loop;
+ int retry_count = 0;
+
+ while (NULL == doc) {
+ doc = xmlParseFile(path);
+ if (NULL != doc) {
+ break;
+ }
+
+ if (MA_RETRY_COUNT == retry_count++) {
+ MAS_LOGE("[ERROR] Fail to parse file error : %s", path);
+ xmlCleanupParser();
+ return -1;
+ }
+ usleep(10000);
+ }
+
+ cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ MAS_LOGE("[ERROR] Empty document");
+ xmlFreeDoc(doc);
+ return -1;
+ }
+
+ if (xmlStrcmp(cur->name, (const xmlChar *) MA_TAG_ASSISTANT_BASE)) {
+ MAS_LOGE("[ERROR] The wrong type, root node is NOT %s", MA_TAG_ASSISTANT_BASE);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+
+ cur = cur->xmlChildrenNode;
+ if (cur == NULL) {
+ MAS_LOGE("[ERROR] Empty document");
+ xmlFreeDoc(doc);
+ return -1;
+ }
+
+ /* alloc assistant info */
+ ma_assistant_info_s temp;
+
+ while (cur != NULL) {
+ if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar *)MA_TAG_ASSISTANT_LANGUAGE_SET)) {
+ xmlNodePtr child_node = cur->xmlChildrenNode;
+ while (child_node != NULL) {
+ 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);
+ MAS_LOGD("Language : %s", key);
+ xmlFree(key);
+ }
+ }
+
+ child_node = child_node->next;
+ }
+ } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar *)MA_TAG_ASSISTANT_WAKEUP_WORD_SET)) {
+ xmlNodePtr child_node = cur->xmlChildrenNode;
+ while (child_node != NULL) {
+ 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);
+ 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);
+ xmlFree(prop);
+ }
+ temp.cnt_wakeup++;
+ }
+
+ child_node = child_node->next;
+ }
+ } 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);
+ 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);
+ 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);
+ 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);
+ MAS_LOGD("Wakeup Engine : %s", key);
+ xmlFree(key);
+ }
+ } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_CUSTOM_UI)) {
+ key = xmlNodeGetContent(cur);
+ if (key) {
+ if (0 == xmlStrcasecmp(key, reinterpret_cast<const xmlChar*>("true"))) {
+ temp.custom_ui_option = true;
+ }
+ 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);
+ }
+ }
+
+ cur = cur->next;
+ }
+
+ if (callback) {
+ callback(&temp, user_data);
+ }
+
+ if (temp.app_id) {
+ free((void*)temp.app_id);
+ }
+ if (temp.name) {
+ free((void*)temp.name);
+ }
+ 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_lang; loop++) {
+ if (temp.supported_lang[loop]) {
+ free((void*)(temp.supported_lang[loop]));
+ }
+ }
+ if (temp.wakeup_engine) {
+ free((void*)temp.wakeup_engine);
+ }
+
+ xmlFreeDoc(doc);
+
+ return 0;
+}
+
+int CServiceConfig::get_assistant_info(service_config_assistant_info_cb callback, void* user_data)
+{
+ const char *suffix = ".xml";
+
+ DIR *d;
+ struct dirent *dir;
+ d = opendir(MA_ASSISTANT_INFO);
+
+ if (d) {
+ while (NULL != (dir = readdir(d))) {
+ if (suffix && strlen(suffix) <= strlen(dir->d_name)) {
+ if (0 == strcmp(dir->d_name + strlen(dir->d_name) - strlen(suffix), suffix)) {
+ char fullpath[_POSIX_PATH_MAX];
+ snprintf(fullpath, _POSIX_PATH_MAX - 1, "%s/%s", MA_ASSISTANT_INFO, dir->d_name);
+ MAS_LOGD("Parsing file : %s\n", fullpath);
+ parse_assistant_info(callback, fullpath, user_data);
+ }
+ }
+ }
+ closedir(d);
+ }
+
+ return 0;
+}
+
+int CServiceConfig::add_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ if (nullptr == wake_word || nullptr == language) return -1;
+
+ bool found = false;
+ for (int loop = 0;false == found && loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+ if (0 == strncmp(wakeup_word_storage[loop], wake_word, MAX_WAKEUP_WORD_LEN) &&
+ 0 == strncmp(wakeup_language_storage[loop], language, MAX_SUPPORTED_LANGUAGE_LEN)) {
+ LOGE("The wakeup word already exists!");
+ return -1; /* Already exists */
+ }
+ if (0 == strlen(wakeup_word_storage[loop])) {
+ strncpy(wakeup_word_storage[loop], wake_word, MAX_WAKEUP_WORD_LEN);
+ wakeup_word_storage[loop][MAX_WAKEUP_WORD_LEN - 1] = '\0';
+ strncpy(wakeup_language_storage[loop], language, MAX_SUPPORTED_LANGUAGE_LEN);
+ wakeup_language_storage[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+ found = true;
+ }
+ }
+ if (!found) {
+ LOGE("No empty slot found while trying to add new wake word!");
+ return -1;
+ }
+ return 0;
+}
+
+int CServiceConfig::remove_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ if (nullptr == wake_word || nullptr == language) return -1;
+
+ bool found = false;
+ for (int loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+ if (0 == strncmp(wakeup_word_storage[loop], wake_word, MAX_WAKEUP_WORD_LEN) &&
+ 0 == strncmp(wakeup_language_storage[loop], language, MAX_SUPPORTED_LANGUAGE_LEN)) {
+ for (int shift = loop;shift < MAX_WAKEUP_WORDS_NUM - 1;shift++) {
+ strncpy(wakeup_word_storage[shift],
+ wakeup_word_storage[shift + 1], MAX_WAKEUP_WORD_LEN);
+ wakeup_word_storage[shift][MAX_WAKEUP_WORD_LEN - 1] = '\0';
+ strncpy(wakeup_language_storage[shift],
+ wakeup_language_storage[shift + 1], MAX_SUPPORTED_LANGUAGE_LEN);
+ wakeup_word_storage[shift][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+ }
+ memset(wakeup_word_storage[MAX_WAKEUP_WORDS_NUM - 1],
+ 0x00, sizeof(char) * MAX_WAKEUP_WORD_LEN);
+ memset(wakeup_language_storage[MAX_WAKEUP_WORDS_NUM - 1],
+ 0x00, sizeof(char) * MAX_SUPPORTED_LANGUAGE_LEN);
+
+ loop--; /* Just in case there are duplicated items */
+ found = true;
+ }
+ }
+ if (!found) return -1;
+ return 0;
+}
+
+int CServiceConfig::load_custom_wake_words(const char* app_id,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ const char delimeter = '|';
+
+ /* 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, delimeter);
+ language_end = strchrnul(language_start, delimeter);
+ if ('\0' == *word_end || '\0' == *language_end) break;
+ *word_end = '\0';
+ *language_end = '\0';
+ if (0 == strlen(word_start)) break;
+ strncpy(wakeup_word_storage[index], word_start, MAX_WAKEUP_WORD_LEN - 1);
+ strncpy(wakeup_language_storage[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_storage[index], wakeup_language_storage[index]);
+ index++;
+ }
+
+ return 0;
+}
+
+int CServiceConfig::save_custom_wake_words(const char* app_id,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ const char* delimeter = "|";
+ /* 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_storage[loop]) > 0) {
+ int wakeup_words_len = strlen(wakeup_words);
+ strncat(wakeup_words, wakeup_word_storage[loop],
+ sizeof(wakeup_words) - wakeup_words_len - 1);
+ strncat(wakeup_words, delimeter, strlen(delimeter));
+ int wakeup_languages_len = strlen(wakeup_languages);
+ strncat(wakeup_languages, wakeup_language_storage[loop],
+ sizeof(wakeup_languages) - wakeup_languages_len - 1);
+ strncat(wakeup_languages, delimeter, strlen(delimeter));
+ }
+ }
+ 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;
+}
+
+int CServiceConfig::get_custom_wake_word_num(
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ int num = 0;
+ for (int loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+ if (0 < strlen(wakeup_word_storage[loop])) {
+ num++;
+ }
+ }
+ return num;
+}
+
+bool CServiceConfig::has_custom_wake_word(const char* wake_word, const char* language,
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN],
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN])
+{
+ if (nullptr == wake_word || nullptr == language) return false;
+
+ for (int loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+ if (0 == strncmp(wakeup_word_storage[loop], wake_word, MAX_WAKEUP_WORD_LEN) &&
+ 0 == strncmp(wakeup_language_storage[loop], language, MAX_SUPPORTED_LANGUAGE_LEN)) {
+ return true;
+ }
+ }
+ return false;
+}
/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ * Copyright 2020 Samsung Electronics Co., Ltd
*
* Licensed under the Flora License, Version 1.1 (the License);
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#include <dbus/dbus.h>
+
#include <dirent.h>
#include <dlfcn.h>
-#include <Ecore.h>
#include <message_port.h>
-#include "multi_assistant_main.h"
-#include "multi_assistant_dbus_server.h"
-#include "multi_assistant_dbus.h"
-
-static DBusConnection* g_conn_sender = NULL;
-static DBusConnection* g_conn_listener = NULL;
-
-static Ecore_Fd_Handler* g_dbus_fd_handler = NULL;
+#include "service_common.h"
+#include "service_main.h"
+#include "service_ipc_dbus.h"
-static int g_streaming_data_serial = 0;
-
-int mas_dbus_reconnect()
+int CServiceIpcDbus::reconnect()
{
- if (!g_conn_sender || !g_conn_listener) {
- mas_dbus_close_connection();
+ if (!mConnectionSender || !mConnectionListener) {
+ close_connection();
- if (0 != mas_dbus_open_connection()) {
+ if (0 != open_connection()) {
MAS_LOGE("[ERROR] Fail to reconnect");
return -1;
}
return 0;
}
- bool sender_connected = dbus_connection_get_is_connected(g_conn_sender);
- bool listener_connected = dbus_connection_get_is_connected(g_conn_listener);
+ bool sender_connected = dbus_connection_get_is_connected(mConnectionSender);
+ bool listener_connected = dbus_connection_get_is_connected(mConnectionListener);
MAS_LOGW("[DBUS] Sender(%s) Listener(%s)",
sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
if (false == sender_connected || false == listener_connected) {
- mas_dbus_close_connection();
+ close_connection();
- if (0 != mas_dbus_open_connection()) {
+ if (0 != open_connection()) {
MAS_LOGE("[ERROR] Fail to reconnect");
return -1;
}
return 0;
}
-static int __dbus_check()
+int CServiceIpcDbus::__dbus_check()
{
- if (NULL == g_conn_sender || NULL == g_conn_listener) {
+ if (NULL == mConnectionSender || NULL == mConnectionListener) {
MAS_LOGE("[ERROR] NULL connection");
- return mas_dbus_reconnect();
+ return reconnect();
}
return 0;
}
-int mas_check_dbus_connection()
+int CServiceIpcDbus::mas_check_dbus_connection()
{
- if (NULL == g_conn_sender || NULL == g_conn_listener) {
- MAS_LOGE("[ERROR] NULL connection sender(%p), listener(%p)", g_conn_sender, g_conn_listener);
+ if (NULL == mConnectionSender || NULL == mConnectionListener) {
+ MAS_LOGE("[ERROR] NULL connection sender(%p), listener(%p)", mConnectionSender, mConnectionListener);
return -1;
}
return 0;
}
-int masc_dbus_send_hello(int pid)
+int CServiceIpcDbus::send_hello(int pid)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
int result = -1;
DBusMessage* result_msg = NULL;
- result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, 500, &err);
+ result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
return result;
}
-int masc_dbus_send_error_message(int reason, const char* err_msg)
+int CServiceIpcDbus::send_error_message(int reason, const char* err_msg)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
}
- if (NULL == g_conn_sender) {
+ if (NULL == mConnectionSender) {
MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
return -1;
}
dbus_message_set_no_reply(msg, TRUE);
- if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
} else {
MAS_LOGI("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
int section;
} streaming_data_streaming_section_header;
-void masc_message_port_error(int error)
+static void masc_message_port_error(int error)
{
MAS_LOGE("message_port error found : %s",
(MESSAGE_PORT_ERROR_NONE == error) ? "MESSAGE_PORT_ERROR_NONE" :
"MESSAGE_PORT_ERROR_UNKNOWN");
}
-int masc_dbus_send_streaming_audio_data(int pid, int event, unsigned char* data, unsigned int data_size)
+int CServiceIpcDbus::send_streaming_audio_data(int pid, int event, void* data, unsigned int data_size)
{
+ if (nullptr == mClientManager) {
+ MAS_LOGE("mClientManager variable is NULL");
+ return -1;
+ }
+
static unsigned char pending_buffer[STREAMING_BUFFER_SIZE];
static unsigned int pending_buffer_size = 0;
streaming_data_header header;
header.streaming_data_type = 0;
header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_audio_data_header) + data_size;
- header.streaming_data_serial = g_streaming_data_serial++;
+ header.streaming_data_serial = mStreamingDataSerial++;
streaming_data_audio_data_header audio_data_header;
audio_data_header.event = event;
if (b) {
bundle_add_byte(b, "content", pending_buffer, pending_buffer_size);
int ret = message_port_send_message(
- mas_get_client_appid_by_pid(pid), message_port, b);
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
if (MESSAGE_PORT_ERROR_NONE != ret)
masc_message_port_error(ret);
if (b) {
bundle_add_byte(b, "content", buffer, total_size);
int ret = message_port_send_message(
- mas_get_client_appid_by_pid(pid), message_port, b);
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
if (MESSAGE_PORT_ERROR_NONE != ret)
masc_message_port_error(ret);
return 0;
}
-int masc_dbus_active_state_change(int pid, int state)
+int CServiceIpcDbus::change_active_state(int pid, int state)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
MA_CLIENT_SERVICE_INTERFACE,
MAS_METHOD_ACTIVE_STATE_CHANGE);
- static int count = 0;
if (NULL == msg) {
MAS_LOGE(">>>> Request mas send activate message : Fail to make message");
return -1; // MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
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);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_dbus_send_preprocessing_information(int pid, const char* app_id)
+int CServiceIpcDbus::send_preprocessing_information(int pid, const char* app_id)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
MA_CLIENT_SERVICE_INTERFACE,
MAS_METHOD_SEND_PREPROCESSING_INFORMATION);
- static int count = 0;
if (NULL == msg) {
MAS_LOGE(">>>> Request mas send preprocessing assistant information : Fail to make message");
return -1; // MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
if (temp_app_id)
free(temp_app_id);
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing assistant information : %d %s", pid, app_id);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_dbus_send_streaming_section_changed(int pid, int section)
+int CServiceIpcDbus::send_streaming_section_changed(int pid, int section)
{
- static int serial = 0;
+ if (nullptr == mClientManager) {
+ MAS_LOGE("mClientManager variable is NULL");
+ return -1;
+ }
+
bundle *b = bundle_create();
streaming_data_header header;
header.streaming_data_type = 1;
header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_streaming_section_header);
- header.streaming_data_serial = g_streaming_data_serial++;
+ header.streaming_data_serial = mStreamingDataSerial++;
streaming_data_streaming_section_header streaming_section_header;
streaming_section_header.section = section;
total_size += sizeof(streaming_section_header);
bundle_add_byte(b, "content", buffer, total_size);
- int ret = message_port_send_message(mas_get_client_appid_by_pid(pid), message_port, b);
+ int ret = message_port_send_message(
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
if (MESSAGE_PORT_ERROR_NONE != ret)
masc_message_port_error(ret);
return 0;
}
-int masc_dbus_send_preprocessing_result(int pid, bool result)
+int CServiceIpcDbus::send_preprocessing_result(int pid, bool result)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
MA_CLIENT_SERVICE_INTERFACE,
MAS_METHOD_SEND_PREPROCESSING_RESULT);
- static int count = 0;
if (NULL == msg) {
MAS_LOGE(">>>> Request mas send preprocessing result : Fail to make message");
return -1; // MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing result : %d %d", pid, temp_result);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_dbus_send_wakeup_engine_command(int pid, const char* command)
+int CServiceIpcDbus::send_wakeup_engine_command(int pid, const char* command)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
MA_CLIENT_SERVICE_INTERFACE,
MAS_METHOD_SEND_WAKEUP_ENGINE_COMMAND);
- static int count = 0;
if (NULL == msg) {
MAS_LOGE(">>>> Request mas send wakeup engine command : Fail to make message");
return -1; // MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
if (temp_command)
free(temp_command);
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[Dbus DEBUG] Success to Send wakeup_engine_command : %d %s", pid, command);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_dbus_service_state_change(int pid, int state)
+int CServiceIpcDbus::change_service_state(int pid, int state)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
MA_CLIENT_SERVICE_INTERFACE,
MAS_METHOD_SERVICE_STATE_CHANGE);
- static int count = 0;
if (NULL == msg) {
MAS_LOGE(">>>> Request mas send service state message : Fail to make message");
return -1; // MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[Dbus DEBUG] Success to Send service state message : %d %d", pid, state);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_dbus_voice_key_status_change(int pid, int status)
+int CServiceIpcDbus::change_voice_key_status(int pid, int status)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
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;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, 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);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_send_hello(void)
+int CServiceIpcDbus::masc_ui_dbus_send_hello(void)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
DBusMessage* result_msg = NULL;
int result = 0;
- result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, 500, &err);
+ result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
return result;
}
-int masc_ui_dbus_send_asr_result(int pid, int event, char* asr_result)
+int CServiceIpcDbus::masc_ui_dbus_send_asr_result(int pid, int event, const char* asr_result)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
if (NULL != temp_asr_result) {
free(temp_asr_result);
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json)
+int CServiceIpcDbus::masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json)
{
if (0 != __dbus_check()) {
return -1; //MA_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; //MA_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send result");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
if (temp_display_text)
free(temp_display_text);
return -1; //MA_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send result");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_change_assistant(char* app_id)
+int CServiceIpcDbus::masc_ui_dbus_change_assistant(const char* app_id)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send change assistant request");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_send_error_message(int reason, const char* err_msg)
+int CServiceIpcDbus::masc_ui_dbus_send_error_message(int reason, const char* err_msg)
{
- if (NULL == g_conn_sender) {
+ if (NULL == mConnectionSender) {
MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
return -1;
}
dbus_message_set_no_reply(msg, TRUE);
- if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
} else {
MAS_LOGD("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_send_recognition_result(int pid, int result)
+int CServiceIpcDbus::masc_ui_dbus_send_recognition_result(int pid, int result)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
return 0;
}
-int masc_ui_dbus_enable_common_ui(int enable)
+int CServiceIpcDbus::masc_ui_dbus_enable_common_ui(int enable)
{
if (0 != __dbus_check()) {
return -1; //MAS_ERROR_OPERATION_FAILED;
dbus_message_set_no_reply(msg, TRUE);
- if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
MAS_LOGE("[Dbus ERROR] Fail to Send");
return -1; // MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
- dbus_connection_flush(g_conn_sender);
+ dbus_connection_flush(mConnectionSender);
}
dbus_message_unref(msg);
static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
{
- if (NULL == g_conn_listener) return ECORE_CALLBACK_RENEW;
+ CServiceIpcDbus* service_ipc = static_cast<CServiceIpcDbus*>(data);
+ if (NULL == service_ipc) {
+ MAS_LOGE("Error : service_ipc NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ DBusConnection* mConnectionListener = service_ipc->get_connection_listener();
+ if (NULL == mConnectionListener) {
+ MAS_LOGE("Error : mConnectionListener NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
- dbus_connection_read_write_dispatch(g_conn_listener, 50);
+ CServiceIpcDbusDispatcher* dispatcher = service_ipc->get_dispatcher();
+ if (NULL == dispatcher) {
+ MAS_LOGE("Error : dispatcher NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ dbus_connection_read_write_dispatch(mConnectionListener, 50);
while (1) {
DBusMessage* msg = NULL;
- msg = dbus_connection_pop_message(g_conn_listener);
+ msg = dbus_connection_pop_message(mConnectionListener);
- if (true != dbus_connection_get_is_connected(g_conn_listener)) {
+ if (true != dbus_connection_get_is_connected(mConnectionListener)) {
MAS_LOGE("[ERROR] Connection is disconnected");
return ECORE_CALLBACK_RENEW;
}
/* client event */
if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_HELLO)) {
- ma_service_dbus_hello(g_conn_listener, msg);
+ dispatcher->on_hello(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_INITIALIZE)) {
- ma_service_dbus_initialize(g_conn_listener, msg);
+ dispatcher->on_initialize(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_DEINITIALIZE)) {
- ma_service_dbus_deinitialize(g_conn_listener, msg);
+ dispatcher->on_deinitialize(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_FORMAT)) {
- ma_service_dbus_get_audio_format(g_conn_listener, msg);
+ dispatcher->on_get_audio_format(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_SOURCE_TYPE)) {
- ma_service_dbus_get_audio_source_type(g_conn_listener, msg);
+ dispatcher->on_get_audio_source_type(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASR_RESULT)) {
- ma_service_dbus_send_asr_result(g_conn_listener, msg);
+ dispatcher->on_send_asr_result(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RESULT)) {
- ma_service_dbus_send_result(g_conn_listener, msg);
+ dispatcher->on_send_result(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RECOGNITION_RESULT)) {
- ma_service_dbus_send_recognition_result(g_conn_listener, msg);
+ dispatcher->on_send_recognition_result(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_START_STREAMING_AUDIO_DATA)) {
- ma_service_dbus_start_streaming_audio_data(g_conn_listener, msg);
+ dispatcher->on_start_streaming_audio_data(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_STOP_STREAMING_AUDIO_DATA)) {
- ma_service_dbus_stop_streaming_audio_data(g_conn_listener, msg);
+ dispatcher->on_stop_streaming_audio_data(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE)) {
- ma_service_dbus_update_voice_feedback_state(g_conn_listener, msg);
+ dispatcher->on_update_voice_feedback_state(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASSISTANT_SPECIFIC_COMMAND)) {
- ma_service_dbus_send_assistant_specific_command(g_conn_listener, msg);
+ dispatcher->on_send_assistant_specific_command(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_BACKGROUND_VOLUME)) {
- ma_service_dbus_set_background_volume(g_conn_listener, msg);
+ dispatcher->on_set_background_volume(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_PREPROCESSING_ALLOW_MODE)) {
- ma_service_dbus_set_preprocessing_allow_mode(g_conn_listener, msg);
+ dispatcher->on_set_preprocessing_allow_mode(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_PREPROCESSING_RESULT)) {
- ma_service_dbus_send_preprocessing_result(g_conn_listener, msg);
+ dispatcher->on_send_preprocessing_result(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG)) {
- ma_service_dbus_set_wake_word_audio_require_flag(g_conn_listener, msg);
+ dispatcher->on_set_wake_word_audio_require_flag(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_ASSISTANT_WAKEUP_LANGUAGE)) {
- ma_service_dbus_set_assistant_language(g_conn_listener, msg);
+ dispatcher->on_set_assistant_language(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_ADD_WAKE_WORD)) {
+ dispatcher->on_add_wake_word(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_REMOVE_WAKE_WORD)) {
+ dispatcher->on_remove_wake_word(mConnectionListener, 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);
+ dispatcher->on_ui_initialize(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_DEINITIALIZE)) {
- ma_service_ui_dbus_deinitialize(g_conn_listener, msg);
+ dispatcher->on_ui_deinitialize(mConnectionListener, msg);
} else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_CHANGE_ASSISTANT)) {
- ma_service_ui_dbus_change_assistant(g_conn_listener, msg);
+ dispatcher->on_ui_change_assistant(mConnectionListener, msg);
} else {
MAS_LOGD("Message is NOT valid");
return ECORE_CALLBACK_RENEW;
}
-static void __mas_dbus_connection_free()
+void CServiceIpcDbus::connection_free()
{
- if (NULL != g_conn_listener) {
- dbus_connection_close(g_conn_listener);
- dbus_connection_unref(g_conn_listener);
- g_conn_listener = NULL;
+ if (NULL != mConnectionListener) {
+ dbus_connection_close(mConnectionListener);
+ dbus_connection_unref(mConnectionListener);
+ mConnectionListener = NULL;
}
- if (NULL != g_conn_sender) {
- dbus_connection_close(g_conn_sender);
- dbus_connection_unref(g_conn_sender);
- g_conn_sender = NULL;
+ if (NULL != mConnectionSender) {
+ dbus_connection_close(mConnectionSender);
+ dbus_connection_unref(mConnectionSender);
+ mConnectionSender = NULL;
}
}
-int mas_dbus_open_connection()
+int CServiceIpcDbus::open_connection()
{
DBusError err;
dbus_error_init(&err);
int ret;
/* Create connection for sender */
- g_conn_sender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
+ mConnectionSender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
dbus_error_free(&err);
}
- if (NULL == g_conn_sender) {
+ if (NULL == mConnectionSender) {
MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
return -1;
}
- dbus_connection_set_exit_on_disconnect(g_conn_sender, false);
+ dbus_connection_set_exit_on_disconnect(mConnectionSender, false);
/* connect to the bus and check for errors */
- g_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
+ mConnectionListener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
dbus_error_free(&err);
}
- if (NULL == g_conn_listener) {
+ if (NULL == mConnectionListener) {
MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
- __mas_dbus_connection_free();
+ connection_free();
return -1;
}
- dbus_connection_set_exit_on_disconnect(g_conn_listener, false);
+ dbus_connection_set_exit_on_disconnect(mConnectionListener, false);
/* request our name on the bus and check for errors */
- ret = dbus_bus_request_name(g_conn_listener, MA_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
+ ret = dbus_bus_request_name(mConnectionListener, MA_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
printf("Fail to be primary owner in dbus request.");
MAS_LOGE("[Dbus ERROR] Fail to be primary owner");
- __mas_dbus_connection_free();
+ connection_free();
return -1;
}
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
dbus_error_free(&err);
- __mas_dbus_connection_free();
+ connection_free();
return -1;
}
/* Flush messages which are received before fd event handler registration */
- while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status(g_conn_listener)) {
- listener_event_callback(NULL, NULL);
+ while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status(mConnectionListener)) {
+ listener_event_callback(this, NULL);
}
/* add a rule for getting signal */
snprintf(rule, 128, "type='signal',interface='%s'", MA_SERVER_SERVICE_INTERFACE);
/* add a rule for which messages we want to see */
- dbus_bus_add_match(g_conn_listener, rule, &err);/* see signals from the given interface */
+ dbus_bus_add_match(mConnectionListener, rule, &err);/* see signals from the given interface */
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
dbus_error_free(&err);
- __mas_dbus_connection_free();
+ connection_free();
return -1;
}
int fd = 0;
- if (1 != dbus_connection_get_unix_fd(g_conn_listener, &fd)) {
+ if (1 != dbus_connection_get_unix_fd(mConnectionListener, &fd)) {
MAS_LOGE("fail to get fd from dbus ");
- __mas_dbus_connection_free();
+ connection_free();
return -1;
} else {
MAS_LOGD("Get fd from dbus : %d", fd);
}
- g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn_listener, NULL, NULL);
+ mFdHandler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, this, NULL, NULL);
- if (NULL == g_dbus_fd_handler) {
+ if (NULL == mFdHandler) {
MAS_LOGE("[Dbus ERROR] Fail to get fd handler");
- __mas_dbus_connection_free();
+ connection_free();
return -1;
}
return 0;
}
-int mas_dbus_close_connection()
+int CServiceIpcDbus::close_connection()
{
DBusError err;
dbus_error_init(&err);
- if (NULL != g_dbus_fd_handler) {
- ecore_main_fd_handler_del(g_dbus_fd_handler);
- g_dbus_fd_handler = NULL;
+ if (NULL != mFdHandler) {
+ ecore_main_fd_handler_del(mFdHandler);
+ mFdHandler = NULL;
}
- dbus_bus_release_name(g_conn_listener, MA_SERVER_SERVICE_NAME, &err);
+ dbus_bus_release_name(mConnectionListener, MA_SERVER_SERVICE_NAME, &err);
if (dbus_error_is_set(&err)) {
MAS_LOGE("[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
dbus_error_free(&err);
}
- __mas_dbus_connection_free();
+ connection_free();
return 0;
}
/*
- * Copyright 2018-2019 Samsung Electronics Co., Ltd
+ * Copyright 2020 Samsung Electronics Co., Ltd
*
* Licensed under the Flora License, Version 1.1 (the License);
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#include "multi_assistant_main.h"
-#include "multi_assistant_dbus.h"
-#include "multi_assistant_dbus_server.h"
-#include "multi_assistant_service_client.h"
+#include <stdlib.h>
+
+#include "service_common.h"
+#include "service_ipc_dbus_dispatcher.h"
+#include "service_main.h"
/*
* Dbus Client-Daemon Server
*/
-int ma_service_dbus_hello(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_hello(DBusConnection* conn, DBusMessage* msg)
{
MAS_LOGD("[DEBUG] MAS HELLO");
return 0;
}
-int ma_service_dbus_initialize(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_initialize(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas initialize : pid(%d)", pid);
- ret = mas_client_initialize(pid);
+ ret = mIpcObserver->on_initialize(pid);
}
DBusMessage* reply;
MAS_LOGE("[OUT ERROR] mas initialize : Fail to create reply message!!");
}
- return 0;
+ return ret;
}
-int ma_service_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_deinitialize(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas deinitialize : pid(%d)", pid);
- ret = mas_client_deinitialize(pid);
+ ret = mIpcObserver->on_deinitialize(pid);
}
DBusMessage* reply;
return 0;
}
-int ma_service_dbus_get_audio_format(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_get_audio_format(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas get audio format");
- ret = mas_client_get_audio_format(pid, &rate, &channel, &audio_type);
+ ret = mIpcObserver->on_get_audio_format(pid, rate, channel, audio_type);
}
DBusMessage* reply;
MAS_LOGE("[OUT ERROR] tts default voice : Fail to create reply message!!");
}
- return 0;
+ return ret;
}
-int ma_service_dbus_get_audio_source_type(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_get_audio_source_type(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
int pid = -1;
- char *type = NULL;
+ std::string type;
int ret;
dbus_message_get_args(msg, &err,
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas get audio source type");
- ret = mas_client_get_audio_source_type(pid, &type);
+ ret = mIpcObserver->on_get_audio_source_type(pid, type);
}
DBusMessage* reply;
char* temp_type = NULL;
- if (type)
- temp_type = strdup(type);
- else
+ if (-1 == ret)
temp_type = strdup("#NULL");
+ else
+ temp_type = strdup(type.c_str());
if (NULL != reply) {
/* Append result and voice */
if (temp_type)
free(temp_type);
- return 0;
+ return ret;
}
-int ma_service_dbus_send_asr_result(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_send_asr_result(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send asr result : pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
- ret = mas_client_send_asr_result(pid, event, asr_result);
+ ret = mIpcObserver->on_send_asr_result(pid, event,
+ asr_result ? std::string{asr_result} : std::string{});
}
DBusMessage* reply;
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_send_result(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_send_result(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send result : pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
- ret = mas_client_send_result(pid, display_text, utterance_text, result_json);
+ ret = mIpcObserver->on_send_result(pid,
+ display_text ? std::string{display_text} : std::string{},
+ utterance_text ? std::string{utterance_text} : std::string{},
+ result_json ? std::string{result_json} : std::string{});
}
DBusMessage* reply;
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_send_recognition_result(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_send_recognition_result(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send recognition result : pid(%d), result(%d)", pid, result);
- ret = mas_client_send_recognition_result(pid, result);
+ ret = mIpcObserver->on_send_recognition_result(pid, result);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send start streaming : pid(%d), type(%d)", pid, type);
- ret = mas_client_start_streaming_audio_data(pid, type);
+ ret = mIpcObserver->on_start_streaming_audio_data(pid, type);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas stop streaming : pid(%d), type(%d)", pid, type);
- ret = mas_client_stop_streaming_audio_data(pid, type);
+ ret = mIpcObserver->on_stop_streaming_audio_data(pid, type);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas update voice feedback : pid(%d), state(%d)", pid, state);
- ret = mas_client_update_voice_feedback_state(pid, state);
+ ret = mIpcObserver->on_update_voice_feedback_state(pid, state);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_send_assistant_specific_command(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_send_assistant_specific_command(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send assistant specific command : pid(%d), command(%s)", pid, command);
- ret = mas_client_set_assistant_specific_command(pid, command);
+ ret = mIpcObserver->on_send_assistant_specific_command(pid,
+ command ? std::string{command} : std::string{});
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_set_background_volume(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_set_background_volume(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas set background volume : pid(%d), ratio(%f)", pid, ratio);
- ret = mas_client_set_background_volume(pid, ratio);
+ ret = mIpcObserver->on_set_background_volume(pid, ratio);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_set_preprocessing_allow_mode(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_set_preprocessing_allow_mode(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
dbus_error_free(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
- char* temp_app_id = NULL;
- if (NULL != app_id && strcmp("#NULL", app_id)) {
- temp_app_id = strdup(app_id);
- }
- MAS_LOGI("[IN] mas set preprocessing allow mode : pid(%d), mode(%d), app_id(%s)", pid, mode, temp_app_id);
- ret = mas_client_set_preprocessing_allow_mode(pid, mode, temp_app_id);
- if (NULL != temp_app_id)
- free(temp_app_id);
+ MAS_LOGI("[IN] mas set preprocessing allow mode : pid(%d), mode(%d), app_id(%s)", pid, mode, app_id);
+ ret = mIpcObserver->on_set_preprocessing_allow_mode(pid,
+ static_cast<ma_preprocessing_allow_mode_e>(mode),
+ app_id ? std::string{app_id} : std::string{});
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_send_preprocessing_result(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_send_preprocessing_result(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas send preprocessing result : pid(%d), result(%d)", pid, result);
- ret = mas_client_send_preprocessing_result(pid, (bool)result);
+ ret = mIpcObserver->on_send_preprocessing_result(pid, result);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_set_wake_word_audio_require_flag(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_set_wake_word_audio_require_flag(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas set wake word audio require flag : pid(%d), require(%d)", pid, require);
- ret = mas_client_set_wake_word_audio_require_flag(pid, (bool)require);
+ ret = mIpcObserver->on_set_wake_word_audio_require_flag(pid, require);
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_dbus_set_assistant_language(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_set_assistant_language(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGI("[IN] mas set assistant language : pid(%d), language(%s)", pid, language);
- ret = mas_client_set_assistant_language(pid, language);
+ ret = mIpcObserver->on_set_assistant_language(pid,
+ language ? std::string{language} : std::string{});
}
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
+ return ret;
}
-int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_add_wake_word(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
+ 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 = mIpcObserver->on_add_wake_word(pid,
+ wake_word ? std::string{wake_word} : std::string{},
+ language ? std::string{language} : std::string{});
+ }
+
+ MAS_LOGD("<<<<<");
+ MAS_LOGD(" ");
+
+ return ret;
+}
+
+int CServiceIpcDbusDispatcher::on_remove_wake_word(DBusConnection* conn, DBusMessage* msg)
+{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ }
+
+ 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 = mIpcObserver->on_remove_wake_word(pid,
+ wake_word ? std::string{wake_word} : std::string{},
+ language ? std::string{language} : std::string{});
+ }
+
+ MAS_LOGD("<<<<<");
+ MAS_LOGD(" ");
+
+ return ret;
+}
+
+int CServiceIpcDbusDispatcher::on_ui_initialize(DBusConnection* conn, DBusMessage* msg)
+{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas ui initialize : pid(%d)", pid);
- ret = mas_ui_client_initialize(pid);
+ ret = mIpcObserver->on_ui_initialize(pid);
}
DBusMessage* reply;
MAS_LOGE("[OUT ERROR] mas ui initialize : Fail to create reply message!!");
}
- return 0;
+ return ret;
}
-int ma_service_ui_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_ui_deinitialize(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas ui deinitialize : pid(%d)", pid);
- ret = mas_ui_client_deinitialize(pid);
+ ret = mIpcObserver->on_ui_deinitialize(pid);
}
DBusMessage* reply;
MAS_LOGE("[OUT ERROR] mas ui deinitialize : Fail to create reply message!!");
}
- return 0;
+ return ret;
}
-int ma_service_ui_dbus_change_assistant(DBusConnection* conn, DBusMessage* msg)
+int CServiceIpcDbusDispatcher::on_ui_change_assistant(DBusConnection* conn, DBusMessage* msg)
{
+ if (nullptr == mIpcObserver) {
+ MAS_LOGE("mIpcObserver variable is NULL");
+ return -1;
+ }
+
DBusError err;
dbus_error_init(&err);
ret = -1; //MAS_ERROR_OPERATION_FAILED;
} else {
MAS_LOGD("[IN] mas ui change assisant : app_id(%s)", app_id);
- ret = mas_ui_client_change_assistant(app_id);
+ ret = mIpcObserver->on_ui_change_assistant(
+ app_id ? std::string{app_id} : std::string{});
}
DBusMessage* reply;
MAS_LOGD("<<<<<");
MAS_LOGD(" ");
- return 0;
-}
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <tizen.h>
+#include <service_app.h>
+#include <app_manager.h>
+#include <app.h>
+#include <malloc.h>
+#include <Ecore.h>
+#include <vconf.h>
+#include <pkgmgr-info.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include "service_common.h"
+#include "service_main.h"
+#include "service_plugin.h"
+#include "service_ipc_dbus.h"
+#include "service_config.h"
+
+static CServiceMain* g_service_main = nullptr;
+
+bool CServiceMain::check_preprocessing_assistant_exists()
+{
+ bool ret = false;
+
+ boost::optional<std::string> preprocessing_appid =
+ mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+ if (preprocessing_appid) {
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ strncmp((*preprocessing_appid).c_str(), mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ if (mClientManager.check_client_validity_by_appid(*preprocessing_appid)) {
+ ret = true;
+ }
+ }
+ }
+ }
+
+ MAS_LOGD("result : %d", ret);
+
+ return ret;
+}
+
+bool CServiceMain::is_current_preprocessing_assistant(const char* appid)
+{
+ if (NULL == appid) return false;
+
+ bool ret = false;
+
+ boost::optional<std::string> preprocessing_appid =
+ mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+ if (preprocessing_appid) {
+ if (strncmp((*preprocessing_appid).c_str(), appid, MAX_APPID_LEN) == 0) {
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_type)
+{
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ int ret = mServicePlugin.get_recording_audio_format(rate, channel, audio_type);
+ if (0 != ret){
+ MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret);
+ }
+
+ return ret;
+}
+
+#define MAX_LOCAL_VARIABLE_STRING_LEN 256
+int CServiceMain::mas_client_get_audio_source_type(int pid, char** type)
+{
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ if (NULL == type) return -1;
+
+ static char cached[MAX_LOCAL_VARIABLE_STRING_LEN] = {'\0'};
+ int ret = mServicePlugin.get_recording_audio_source_type(type);
+ if (0 != ret){
+ MAS_LOGE("[ERROR] Fail to get recording audio source type, ret(%d)", ret);
+ *type = cached;
+ } else if (*type) {
+ strncpy(cached, *type, MAX_LOCAL_VARIABLE_STRING_LEN - 1);
+ cached[MAX_LOCAL_VARIABLE_STRING_LEN - 1] = '\0';
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_client_send_preprocessing_information(int pid)
+{
+ int ret = -1;
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ boost::optional<std::string> preprocessing_appid =
+ mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+ if (preprocessing_appid) {
+ MAS_LOGD("preprocessing_assistant_appid : %s", (*preprocessing_appid).c_str());
+ ret = mServiceIpc.send_preprocessing_information(pid, (*preprocessing_appid).c_str());
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_client_send_voice_key_status_change(int pid, ma_voice_key_status_e status)
+{
+ int ret = -1;
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ ret = mServiceIpc.change_voice_key_status(pid, status);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send voice key status changed information, ret(%d)", ret);
+ }
+ mLastVoiceKeyStatus = status;
+
+ return ret;
+}
+
+int CServiceMain::mas_client_send_asr_result(int pid, int event, const char* asr_result)
+{
+ MAS_LOGD("[Enter] pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
+ int ret = mServiceIpc.masc_ui_dbus_send_asr_result(pid, event, asr_result);
+ if (0 != ret){
+ MAS_LOGE("[ERROR] Fail to send asr result, ret(%d)", ret);
+ }
+
+ // if final event is , launch assistant app which is invoked with wakeup word.
+ /* TO_DO */
+ return ret;
+}
+
+int CServiceMain::mas_client_send_result(int pid, const char* display_text,
+ const char* utterance_text, const char* result_json)
+{
+ MAS_LOGD("[Enter] pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json);
+ int ret = mServiceIpc.masc_ui_dbus_send_result(pid, display_text, utterance_text, result_json);
+ if (0 != ret){
+ MAS_LOGE("[ERROR] Fail to send result, ret(%d)", ret);
+ }
+
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ mServicePlugin.update_recognition_result(pid_appid.c_str(), MA_RECOGNITION_RESULT_EVENT_SUCCESS);
+
+ return ret;
+}
+
+int CServiceMain::mas_client_send_recognition_result(int pid, int result)
+{
+ MAS_LOGD("[Enter] pid(%d), result(%d)", pid, result);
+ int ret = mServiceIpc.masc_ui_dbus_send_recognition_result(pid, result);
+ if (0 != ret){
+ MAS_LOGE("[ERROR] Fail to send recognition result, ret(%d)", ret);
+ }
+
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ mServicePlugin.update_recognition_result(pid_appid.c_str(), result);
+
+ return ret;
+}
+
+int CServiceMain::mas_client_start_streaming_audio_data(int pid, int type)
+{
+ int ret = -1;
+ switch(type) {
+ case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
+ ret = mServicePlugin.start_streaming_utterance_data();
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED);
+ break;
+ case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
+ ret = mServicePlugin.start_streaming_previous_utterance_data();
+ /* Preprocessing is not required for previous utterance streaming */
+ break;
+ case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
+ ret = mServicePlugin.start_streaming_follow_up_data();
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED);
+ break;
+ }
+ return ret;
+}
+
+int CServiceMain::mas_client_stop_streaming_audio_data(int pid, int type)
+{
+ int ret = -1;
+ switch(type) {
+ case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE:
+ ret = mServicePlugin.stop_streaming_utterance_data();
+ break;
+ case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE:
+ ret = mServicePlugin.stop_streaming_previous_utterance_data();
+ break;
+ case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH:
+ ret = mServicePlugin.stop_streaming_follow_up_data();
+ break;
+ }
+ return ret;
+}
+
+int CServiceMain::mas_client_update_voice_feedback_state(int pid, int state)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ mServicePlugin.update_voice_feedback_state(pid_appid.c_str(), state);
+ return 0;
+}
+
+int CServiceMain::mas_client_set_assistant_specific_command(int pid, const char *command)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ mServicePlugin.set_assistant_specific_command(pid_appid.c_str(), command);
+ return 0;
+}
+
+int CServiceMain::mas_client_set_background_volume(int pid, double ratio)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ mServicePlugin.set_background_volume(pid_appid.c_str(), ratio);
+ return 0;
+}
+
+int CServiceMain::mas_client_set_preprocessing_allow_mode(int pid, ma_preprocessing_allow_mode_e mode, const char* appid)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used) {
+ if (0 == pid_appid.compare(mClientInfo[loop].appid)) {
+ mClientInfo[loop].preprocessing_allow_mode = mode;
+ if (appid) {
+ strncpy(mClientInfo[loop].preprocessing_allow_appid, appid, MAX_APPID_LEN);
+ mClientInfo[loop].preprocessing_allow_appid[MAX_APPID_LEN - 1] = '\0';
+ } else {
+ mClientInfo[loop].preprocessing_allow_appid[0] = '\0';
+ }
+ }
+ }
+ }
+
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED);
+
+ return 0;
+}
+
+int CServiceMain::mas_client_send_preprocessing_result(int pid, bool result)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+ if (!is_current_preprocessing_assistant(pid_appid.c_str())) return -1;
+
+ const char *current_maclient_appid = NULL;
+ if (mCurrentClientInfo >= 0 && mCurrentClientInfo < MAX_MACLIENT_INFO_NUM) {
+ current_maclient_appid = mClientInfo[mCurrentClientInfo].appid;
+ }
+
+ if (result) {
+ MAS_LOGD("Preprocessing succeeded, bring (%s) to foreground", pid_appid.c_str());
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED);
+ } else {
+ MAS_LOGD("Preprocessing failed, bring (%s) to foreground", current_maclient_appid);
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED);
+ }
+
+ if (current_maclient_appid) {
+ int pid_by_appid = mClientManager.find_client_pid_by_appid(
+ std::string{current_maclient_appid});
+ mServiceIpc.send_preprocessing_result(pid_by_appid, result);
+ }
+
+ return 0;
+}
+
+int CServiceMain::mas_client_set_wake_word_audio_require_flag(int pid, bool require)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+
+ mServicePlugin.set_wake_word_audio_require_flag(pid_appid.c_str(), require);
+ return 0;
+}
+
+int CServiceMain::mas_client_set_assistant_language(int pid, const char* language)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+
+ mServicePlugin.set_assistant_language(pid_appid.c_str(), language);
+ return 0;
+}
+
+int CServiceMain::mas_client_add_wake_word(int pid, const char* wake_word, const char* language)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 == pid_appid.compare(mClientInfo[loop].appid)) {
+ int ret = mServiceConfig.add_custom_wake_word(wake_word, language,
+ mClientInfo[loop].wakeup_word,
+ mClientInfo[loop].wakeup_language);
+ if (0 == ret) {
+ mServiceConfig.save_custom_wake_words(pid_appid.c_str(),
+ mClientInfo[loop].wakeup_word,
+ mClientInfo[loop].wakeup_language);
+ } else {
+ LOGE("add new wake word failed!");
+ return -1;
+ }
+ }
+ }
+
+ mServicePlugin.add_assistant_wakeup_word(pid_appid.c_str(), wake_word, language);
+ return 0;
+}
+
+int CServiceMain::mas_client_remove_wake_word(int pid, const char* wake_word, const char* language)
+{
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ }
+
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 == pid_appid.compare(mClientInfo[loop].appid)) {
+ int ret = mServiceConfig.remove_custom_wake_word(wake_word, language,
+ mClientInfo[loop].wakeup_word,
+ mClientInfo[loop].wakeup_language);
+ if (0 == ret) {
+ mServiceConfig.save_custom_wake_words(pid_appid.c_str(),
+ mClientInfo[loop].wakeup_word,
+ mClientInfo[loop].wakeup_language);
+ }
+ }
+ }
+
+ mServicePlugin.remove_assistant_wakeup_word(pid_appid.c_str(), wake_word, language);
+ return 0;
+}
+
+int CServiceMain::mas_ui_client_initialize(int pid)
+{
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ return 0;
+}
+
+int CServiceMain::mas_ui_client_deinitialize(int pid)
+{
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ return 0;
+}
+
+int CServiceMain::mas_ui_client_change_assistant(const char* appid)
+{
+ MAS_LOGD("[Enter]");
+
+ if (NULL == appid) {
+ MAS_LOGE("NULL parameter");
+ return -1;
+ }
+
+ bool use_custom_ui = mas_get_client_custom_ui_option_by_appid(appid);
+ mServiceIpc.masc_ui_dbus_enable_common_ui(!use_custom_ui);
+
+ mas_set_current_client_by_appid(appid);
+ int pid = mas_get_client_pid_by_appid(appid);
+ if (pid != -1) {
+ mas_bring_client_to_foreground(appid);
+ mas_client_send_preprocessing_information(pid);
+ if (MA_VOICE_KEY_STATUS_PRESSED == mLastVoiceKeyStatus) {
+ mas_client_send_voice_key_status_change(pid, mLastVoiceKeyStatus);
+ }
+
+ mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_ACTIVE);
+ MAS_LOGD("MA Client with appid %s exists, requesting speech data", (appid ? appid : "NULL"));
+ /*
+ int ret = mServicePlugin.start_streaming_utterance_data();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to start streaming utterance data(%d)", ret);
+ }
+ */
+ } else {
+ // Appropriate MA Client not available, trying to launch new one
+ MAS_LOGD("MA Client with appid %s does not exist, launching client", (appid ? appid : "NULL"));
+
+ /* The appid parameter might not exist after this function call, so we use appid string in our mClientInfo */
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid) &&
+ 0 < strlen(mClientInfo[loop].wakeup_word[0])) {
+ if (strncmp(appid, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ mas_launch_client_by_appid(mClientInfo[loop].appid, CLIENT_LAUNCH_MODE_ACTIVATION);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int mas_assistant_info_cb(ma_assistant_info_s* info, void* user_data) {
+ int ret = -1;
+ CServiceMain* service_main = static_cast<CServiceMain*>(user_data);
+ if (service_main) {
+ ret = service_main->add_assistant_info(info);
+ }
+ return ret;
+}
+
+int CServiceMain::add_assistant_info(ma_assistant_info_s* info) {
+ MAS_LOGD("__mas_assistant_info_cb called");
+
+ if (NULL == info) {
+ MAS_LOGE("info NULL, returning");
+ return -1;
+ }
+ if (NULL == info->app_id) {
+ MAS_LOGE("app_id NULL, returning");
+ return -1;
+ }
+
+ int index = -1;
+ int loop = 0;
+ while(-1 == index && loop < MAX_MACLIENT_INFO_NUM) {
+ if (false == mClientInfo[loop].used) {
+ index = loop;
+ }
+ loop++;
+ }
+ if (-1 != index) {
+ mClientInfo[index].used = true;
+ mClientInfo[index].preprocessing_allow_mode = MA_PREPROCESSING_ALLOW_NONE;
+ mClientInfo[index].preprocessing_allow_appid[0] = '\0';
+ MAS_LOGD("app_id(%s)", info->app_id);
+ strncpy(mClientInfo[index].appid, info->app_id, MAX_APPID_LEN);
+ mClientInfo[index].appid[MAX_APPID_LEN - 1] = '\0';
+
+ if (is_current_preprocessing_assistant(mClientInfo[index].appid)) {
+ mCurrentPreprocessingClientInfo = index;
+ }
+
+ for (loop = 0;loop < MAX_WAKEUP_WORDS_NUM;loop++) {
+ 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(mClientInfo[index].wakeup_word[loop], info->wakeup_list[loop], MAX_WAKEUP_WORD_LEN);
+ mClientInfo[index].wakeup_word[loop][MAX_WAKEUP_WORD_LEN - 1] = '\0';
+ if (info->wakeup_language[loop]) {
+ strncpy(mClientInfo[index].wakeup_language[loop], info->wakeup_language[loop], MAX_SUPPORTED_LANGUAGE_LEN);
+ mClientInfo[index].wakeup_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+ } else {
+ strncpy(mClientInfo[index].wakeup_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
+ }
+ } else {
+ strncpy(mClientInfo[index].wakeup_word[loop], "", MAX_WAKEUP_WORD_LEN);
+ }
+ }
+
+ for (loop = 0;loop < MAX_SUPPORTED_LANGUAGES_NUM;loop++) {
+ if (loop < info->cnt_lang && info->supported_lang[loop]) {
+ MAS_LOGD("supported_lang(%d)(%s)", loop, info->supported_lang[loop]);
+ strncpy(mClientInfo[index].supported_language[loop], info->supported_lang[loop], MAX_SUPPORTED_LANGUAGE_LEN);
+ mClientInfo[index].supported_language[loop][MAX_SUPPORTED_LANGUAGE_LEN - 1] = '\0';
+ } else {
+ strncpy(mClientInfo[index].supported_language[loop], "", MAX_SUPPORTED_LANGUAGE_LEN);
+ }
+ }
+
+ MAS_LOGD("wakeup_engine(%s)", info->wakeup_engine);
+ if (info->wakeup_engine) {
+ strncpy(mClientInfo[index].wakeup_engine, info->wakeup_engine, MAX_APPID_LEN);
+ mClientInfo[index].wakeup_engine[MAX_APPID_LEN - 1] = '\0';
+ } else {
+ mClientInfo[index].wakeup_engine[0] = '\0';
+ MAS_LOGW("Wakeup engine information not provided for : %s", info->app_id);
+ }
+ mClientInfo[index].custom_ui_option = info->custom_ui_option;
+
+ MAS_LOGD("voice_key_support_mode(%d)", info->voice_key_support_mode);
+ mClientInfo[index].voice_key_support_mode = info->voice_key_support_mode;
+ MAS_LOGD("voice_key_tap_duration(%f)", info->voice_key_tap_duration);
+ mClientInfo[index].voice_key_tap_duration = info->voice_key_tap_duration;
+ } else {
+ MAS_LOGD("Couldn't find an empty slot for storing assistant info");
+ }
+
+ MAS_LOGD("__mas_assistant_info_cb end");
+
+ return 0;
+}
+
+static void active_state_changed_cb(std::string key, void* user_data)
+{
+ IPreferenceManager* manager = static_cast<IPreferenceManager*>(user_data);
+ if (nullptr == manager) return;
+
+ boost::optional<bool> activated =
+ manager->get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED);
+ if (activated) {
+ MAS_LOGD("multi-assistant active state : %d\n", *activated);
+
+ CServicePlugin *plugin = nullptr;
+ if (g_service_main) {
+ plugin = g_service_main->get_service_plugin();
+ }
+ if (plugin) {
+ if (*activated) {
+ plugin->activate();
+ } else {
+ plugin->deactivate();
+ }
+ } else {
+ MAS_LOGE("Could not change plugin state : %p %p", g_service_main, plugin);
+ }
+ }
+}
+
+int CServiceMain::initialize_service_plugin(void)
+{
+ if (0 != mServicePlugin.initialize()) {
+ MAS_LOGE("Fail to ws intialize");
+ return -1;
+ }
+
+ if (0 != mServicePlugin.set_language(mCurrentLanguage.c_str())) {
+ MAS_LOGE("Fail to ws set language");
+ return -1;
+ }
+
+ memset(&mClientInfo, 0x00, sizeof(mClientInfo));
+ mCurrentClientInfo = -1;
+ mCurrentPreprocessingClientInfo = -1;
+ mWakeupClientAppId.clear();
+
+ if (0 == mServiceConfig.get_assistant_info(mas_assistant_info_cb, this)) {
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ int inner_loop;
+ if (0 < strlen(mClientInfo[loop].appid)) {
+ mServiceConfig.load_custom_wake_words(mClientInfo[loop].appid,
+ mClientInfo[loop].wakeup_word, mClientInfo[loop].wakeup_language);
+ if (0 < strlen(mClientInfo[loop].wakeup_engine)) {
+ mServicePlugin.set_assistant_wakeup_engine(
+ mClientInfo[loop].appid,
+ mClientInfo[loop].wakeup_engine);
+ }
+ for (inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].wakeup_word[inner_loop])) {
+ MAS_LOGD("Registering wakeup word %s for app %s",
+ mClientInfo[loop].wakeup_word[inner_loop], mClientInfo[loop].appid);
+ if (0 != mServicePlugin.add_assistant_wakeup_word(
+ mClientInfo[loop].appid,
+ mClientInfo[loop].wakeup_word[inner_loop],
+ mClientInfo[loop].wakeup_language[inner_loop])) {
+ MAS_LOGE("Fail to add assistant's wakeup word");
+ }
+ }
+ }
+ for (inner_loop = 0; inner_loop < MAX_SUPPORTED_LANGUAGES_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].supported_language[inner_loop])) {
+ MAS_LOGD("Adding language %s for app %s",
+ mClientInfo[loop].supported_language[inner_loop], mClientInfo[loop].appid);
+ if (0 != mServicePlugin.add_assistant_language(
+ mClientInfo[loop].appid,
+ mClientInfo[loop].supported_language[inner_loop])) {
+ MAS_LOGE("Fail to add assistant's language");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ MAS_LOGE("Fail to load assistant info");
+ }
+
+ if (0 != mServicePlugin.set_callbacks()) {
+ MAS_LOGE("Fail to set callbacks");
+ return -1;
+ }
+
+ return 0;
+}
+
+int CServiceMain::deinitialize_service_plugin(void)
+{
+ MAS_LOGI("[ENTER]");
+ if (0 != mServicePlugin.deactivate()) {
+ MAS_LOGE("Fail to deactivate");
+ }
+ if (0 != mServicePlugin.deinitialize()) {
+ MAS_LOGE("Fail to deinitialize");
+ }
+ MAS_LOGI("[END]");
+ return 0;
+}
+
+int CServiceMain::process_activated_setting()
+{
+ if (mPreferenceManager.register_changed_callback(
+ MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb, &mPreferenceManager)) {
+ /* Activate / deactivate according to the vconf key setting */
+ active_state_changed_cb(std::string{}, &mPreferenceManager);
+ } else {
+#ifdef ENABLE_MULTI_ASSISTANT_BY_DEFAULT
+ /* Multi-assistant needs to be enabled by default, unless disabled explicitly */
+ mServicePlugin.activate();
+ const char *default_assistant = NULL;
+ if (0 == mServicePlugin.get_default_assistant(&default_assistant)) {
+ if (NULL == default_assistant) {
+ if (mClientInfo[0].used) {
+ default_assistant = mClientInfo[0].appid;
+ MAS_LOGW("No default assistant, setting %s as default", default_assistant);
+ mServicePlugin.set_default_assistant(default_assistant);
+ } else {
+ MAS_LOGE("No default assistant, and no assistant installed");
+ }
+ }
+ }
+#endif
+ }
+ return 0;
+}
+
+int CServiceMain::mas_get_current_client_pid()
+{
+ int ret = -1;
+ if (mCurrentClientInfo >= 0 && mCurrentClientInfo < MAX_MACLIENT_INFO_NUM) {
+ const char *appid = mClientInfo[mCurrentClientInfo].appid;
+ if (appid) {
+ ret = mClientManager.find_client_pid_by_appid(std::string{appid});
+ }
+ }
+ return ret;
+}
+
+int CServiceMain::mas_get_current_preprocessing_client_pid()
+{
+ int ret = -1;
+ if (mCurrentPreprocessingClientInfo >= 0 && mCurrentPreprocessingClientInfo < MAX_MACLIENT_INFO_NUM) {
+ const char *appid = mClientInfo[mCurrentPreprocessingClientInfo].appid;
+ if (appid) {
+ ret = mClientManager.find_client_pid_by_appid(std::string{appid});
+ }
+ }
+ return ret;
+}
+
+int CServiceMain::mas_get_client_pid_by_appid(const char *appid)
+{
+ int ret = -1;
+
+ if (appid) {
+ ret = mClientManager.find_client_pid_by_appid(std::string{appid});
+ }
+
+ if (-1 != ret && !mApplicationManager.is_application_running(ret)) {
+ MAS_LOGE("The PID for %s was %d, but it seems to be terminated", appid, ret);
+ on_deinitialize(ret);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+bool CServiceMain::mas_get_client_custom_ui_option_by_appid(const char *appid)
+{
+ bool ret = false;
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid) &&
+ 0 < strlen(mClientInfo[loop].wakeup_word[0])) {
+ if (strncmp(appid, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ ret = mClientInfo[loop].custom_ui_option;
+ }
+ }
+ }
+ return ret;
+}
+
+int CServiceMain::mas_get_client_pid_by_wakeup_word(const char *wakeup_word)
+{
+ const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
+ return mas_get_client_pid_by_appid(appid);
+}
+
+const char* CServiceMain::mas_get_client_appid_by_wakeup_word(const char *wakeup_word)
+{
+ int loop;
+ const char *appid = NULL;
+
+ if (NULL == wakeup_word) return NULL;
+
+ for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid)) {
+ for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].wakeup_word[inner_loop])) {
+ if (0 == strncmp(wakeup_word, mClientInfo[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
+ appid = mClientInfo[loop].appid;
+ }
+ }
+ }
+ }
+ }
+
+ /* Perform extended search, by eliminating blank characters */
+ if (NULL == appid) {
+ for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && NULL == appid; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid)) {
+ for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].wakeup_word[inner_loop])) {
+ char comparand[MAX_WAKEUP_WORD_LEN];
+ int comparand_index = 0;
+ for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
+ if (' ' != mClientInfo[loop].wakeup_word[inner_loop][index]) {
+ comparand[comparand_index++] = mClientInfo[loop].wakeup_word[inner_loop][index];
+ }
+ }
+ if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
+ appid = mClientInfo[loop].appid;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return appid;
+}
+
+int CServiceMain::mas_set_current_client_by_wakeup_word(const char *wakeup_word)
+{
+ int loop;
+ int ret = -1;
+ int prev_selection = mCurrentClientInfo;
+
+ for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid)) {
+ for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].wakeup_word[inner_loop])) {
+ if (0 == strncmp(wakeup_word, mClientInfo[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) {
+ mCurrentClientInfo = loop;
+ ret = 0;
+ }
+ }
+ }
+ }
+ }
+ /* Perform extended search, by eliminating blank characters */
+ if (ret == -1) {
+ for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid)) {
+ for (int inner_loop = 0; inner_loop < MAX_WAKEUP_WORDS_NUM; inner_loop++) {
+ if (0 < strlen(mClientInfo[loop].wakeup_word[inner_loop])) {
+ char comparand[MAX_WAKEUP_WORD_LEN];
+ int comparand_index = 0;
+ for (int index = 0; index < MAX_WAKEUP_WORD_LEN; index++) {
+ if (' ' != mClientInfo[loop].wakeup_word[inner_loop][index]) {
+ comparand[comparand_index++] = mClientInfo[loop].wakeup_word[inner_loop][index];
+ }
+ }
+ if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) {
+ mCurrentClientInfo = loop;
+ ret = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mCurrentClientInfo != prev_selection) {
+ if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
+ int pid = mas_get_client_pid_by_appid(mClientInfo[prev_selection].appid);
+ mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_INACTIVE);
+ }
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_set_current_client_by_appid(const char *appid)
+{
+ int ret = -1;
+ int prev_selection = mCurrentClientInfo;
+
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid) &&
+ 0 < strlen(mClientInfo[loop].wakeup_word[0])) {
+ if (strncmp(appid, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ mCurrentClientInfo = loop;
+ ret = 0;
+ }
+ }
+ }
+
+ if (mCurrentClientInfo != prev_selection) {
+ if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) {
+ int pid = mas_get_client_pid_by_appid(mClientInfo[prev_selection].appid);
+ mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_INACTIVE);
+ }
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_launch_client_by_appid(const char *appid, CLIENT_LAUNCH_MODE launch_mode)
+{
+ int result = 0;
+
+ if (NULL == appid || 0 == strlen(appid)) {
+ MAS_LOGE("appid invalid, failed launching MA Client");
+ return -1;
+ }
+
+ if (CLIENT_LAUNCH_MODE_PRELAUNCH == launch_mode) {
+ if (mApplicationManager.is_application_running(appid)) {
+ MAS_LOGE("appid %s is already running, no need for a prelaunch", appid);
+ return -1;
+ }
+
+ result = mApplicationManager.launch_app_async(appid, true);
+ } else {
+ result = mApplicationManager.launch_app_async(appid, false);
+ }
+
+ if (CLIENT_LAUNCH_MODE_ACTIVATION == launch_mode) {
+ bool found = false;
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used &&
+ 0 < strlen(mClientInfo[loop].appid)) {
+ if (strncmp(appid, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ mWakeupClientAppId = mClientInfo[loop].appid;
+ found = true;
+ }
+ }
+ }
+ MAS_LOGD("mWakeupClientAppId : %s, %d", mWakeupClientAppId.c_str(), found);
+ }
+
+ return result;
+}
+
+int CServiceMain::mas_bring_client_to_foreground(const char* appid)
+{
+ int ret = 0;
+
+ if (NULL == appid || 0 == strlen(appid)) {
+ MAS_LOGE("appid invalid, failed launching MA Client");
+ return -1;
+ }
+
+ if (!mApplicationManager.bring_app_to_foreground(appid)) {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int CServiceMain::mas_launch_client_by_wakeup_word(const char *wakeup_word)
+{
+ const char *appid = mas_get_client_appid_by_wakeup_word(wakeup_word);
+ return mas_launch_client_by_appid(appid, CLIENT_LAUNCH_MODE_ACTIVATION);
+}
+
+int CServiceMain::mas_prelaunch_default_assistant()
+{
+ /* CHECK NEEDED : should the code segment below and activation logic above be moved to wakeup manger? */
+ boost::optional<bool> prelaunch_mode =
+ mPreferenceManager.get_bool(WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE);
+ if (prelaunch_mode && *prelaunch_mode) {
+ const char *default_assistant = NULL;
+ if (0 == mServicePlugin.get_default_assistant(&default_assistant)) {
+ if (!(mApplicationManager.is_application_running(default_assistant))) {
+ MAS_LOGD("prelaunching default_assistant_appid : %s", default_assistant);
+ mas_launch_client_by_appid(default_assistant, CLIENT_LAUNCH_MODE_PRELAUNCH);
+ }
+ }
+ }
+ return 0;
+}
+
+int CServiceMain::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 == mServicePlugin.get_default_assistant(&default_assistant)) {
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (mClientInfo[loop].used) {
+ if (default_assistant &&
+ strncmp(default_assistant, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ float duration = mClientInfo[loop].voice_key_tap_duration;
+ if (0.0f < duration) {
+ mServicePlugin.set_voice_key_tap_duration(duration);
+ } else {
+ mServicePlugin.unset_voice_key_tap_duration();
+ }
+ mServicePlugin.set_voice_key_support_mode(
+ mClientInfo[loop].voice_key_support_mode);
+ successful = true;
+ }
+ }
+ }
+ }
+
+ if (!successful) {
+ mServicePlugin.unset_voice_key_tap_duration();
+ mServicePlugin.set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE_NONE);
+ }
+ return 0;
+}
+
+ma_preprocessing_allow_mode_e CServiceMain::get_preprocessing_allow_mode(const char* appid)
+{
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) {
+ if (appid && mClientInfo[loop].used) {
+ if (strncmp(appid, mClientInfo[loop].appid, MAX_APPID_LEN) == 0) {
+ return mClientInfo[loop].preprocessing_allow_mode;
+ }
+ }
+ }
+ return MA_PREPROCESSING_ALLOW_NONE;
+}
+
+/* This might need to be read from settings in the future, but using macro for now */
+//#define BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+
+int CServiceMain::mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT event)
+{
+ const char* current_maclient_appid = NULL;
+ const char* preprocessing_allow_appid = NULL;
+ if (mCurrentClientInfo >= 0 && mCurrentClientInfo < MAX_MACLIENT_INFO_NUM) {
+ current_maclient_appid = mClientInfo[mCurrentClientInfo].appid;
+ preprocessing_allow_appid = mClientInfo[mCurrentClientInfo].preprocessing_allow_appid;
+ }
+ ma_preprocessing_allow_mode_e mode = get_preprocessing_allow_mode(current_maclient_appid);
+
+ switch (event) {
+ case PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED:
+ {
+#ifndef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+ /* If there is no need to bring preprocessing assistant to front,
+ current_maclient should always be brought to front */
+ mas_bring_client_to_foreground(current_maclient_appid);
+#endif
+ mCurrentPreprocessingState = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
+ if (check_preprocessing_assistant_exists()) {
+ if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
+ MA_PREPROCESSING_ALLOW_ALL == mode) {
+ if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
+ }
+ }
+ } else {
+#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+ /* If preprocessing assistant does not exist, there is no way to enable
+ preprocessing assistant, so bring current maclient to front right away */
+ mas_bring_client_to_foreground(current_maclient_appid);
+#endif
+ }
+ }
+ break;
+ case PREPROCESSING_STATE_EVENT_PREPROCESSING_ALLOW_MODE_CHANGED:
+ {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED;
+ /* Enable preprocessing mode only if the preprocessing assistant exists */
+ if (check_preprocessing_assistant_exists()) {
+ if (MA_PREPROCESSING_ALLOW_UTTERANCE == mode ||
+ MA_PREPROCESSING_ALLOW_ALL == mode) {
+ if (is_current_preprocessing_assistant(preprocessing_allow_appid)) {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED;
+ }
+ }
+ }
+ }
+ break;
+ case PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED:
+ {
+ if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_ENABLED == mCurrentPreprocessingState) {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_PREPROCESSING_UTTERANCE;
+ } else if (PREPROCESSING_STATE_WAKEUP_PREPROCESS_DISABLED == mCurrentPreprocessingState) {
+ /* If preprocessing assistant does not exist, the current_maclient
+ would have been brought to front already on wakeup event */
+#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+ if (check_preprocessing_assistant_exists()) {
+ mas_bring_client_to_foreground(current_maclient_appid);
+ }
+#endif
+ mCurrentPreprocessingState = PREPROCESSING_STATE_NONE;
+ }
+ }
+ break;
+ case PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED:
+ {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_NONE;
+ if (check_preprocessing_assistant_exists()) {
+ if (MA_PREPROCESSING_ALLOW_FOLLOW_UP == mode ||
+ MA_PREPROCESSING_ALLOW_ALL == mode) {
+ mCurrentPreprocessingState = PREPROCESSING_STATE_PREPROCESSING_FOLLOW_UP;
+ }
+ }
+ }
+ break;
+ case PREPROCESSING_STATE_EVENT_PREPROCESSING_SUCCEEDED:
+ {
+#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+ if (PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED == mCurrentPreprocessingState ||
+ PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED == mCurrentPreprocessingState) {
+ boost::optional<std::string> preprocessing_assistant =
+ mPreferenceManager.get_bool(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+ if (preprocessing_assistant) {
+ MAS_LOGD("preprocessing_assistant_appid : %s", (*preprocessing_assistant).c_str());
+ mas_bring_client_to_foreground((*preprocessing_assistant).c_str());
+ }
+ }
+#endif
+ mCurrentPreprocessingState = PREPROCESSING_STATE_NONE;
+ }
+ break;
+ case PREPROCESSING_STATE_EVENT_PREPROCESSING_FAILED:
+ {
+#ifdef BRING_PREPROCESSING_ASSISTANT_TO_FRONT
+ if (PREPROCESSING_STATE_EVENT_UTTERANCE_STREAMING_STARTED == mCurrentPreprocessingState ||
+ PREPROCESSING_STATE_EVENT_FOLLOW_UP_STREAMING_STARTED == mCurrentPreprocessingState) {
+ mas_bring_client_to_foreground(current_maclient_appid);
+ }
+#endif
+ mCurrentPreprocessingState = PREPROCESSING_STATE_NONE;
+ }
+ break;
+ }
+ return 0;
+}
+
+int CServiceMain::mas_set_current_service_state(ma_service_state_e state)
+{
+ mCurrentServiceState = state;
+
+ int count = mClientManager.get_client_num();
+ int i;
+
+ for (i = 0; i < count; i++) {
+ int pid = mClientManager.find_client_pid_by_index(i);
+
+ if (-1 != pid) {
+ int ret = mServiceIpc.change_service_state(pid, state);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set service state change to %d, ret(%d)", pid, ret);
+ }
+ }
+ }
+ return 0;
+}
+
+ma_service_state_e CServiceMain::mas_get_current_service_state()
+{
+ return mCurrentServiceState;
+}
+
+bool CServiceMain::is_valid_wakeup_engine(const char* appid)
+{
+ for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM;loop++) {
+ if (mClientInfo[loop].used) {
+ LOGD("comparing appid : %s %s", mClientInfo[loop].wakeup_engine, appid);
+ if (0 == strncmp(mClientInfo[loop].wakeup_engine, appid, MAX_APPID_LEN)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+int pkg_app_list_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ if (nullptr == g_service_main) return -1;
+
+ char *appid = NULL;
+
+ int ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (PMINFO_R_OK == ret && NULL != appid) {
+ int *result = (int*)user_data;
+ if (result) {
+ bool exists = g_service_main->is_valid_wakeup_engine(appid);
+ if (exists) {
+ *result = 1;
+ }
+ }
+ } else {
+ LOGE("pkgmgrinfo_appinfo_get_appid failed! error code=%d", ret);
+ }
+
+ return 0;
+}
+
+/*
+INFO: Package install/update/uninstall scenario
+Install and Uninstall are obviously simple.
+ Install: just INSTALL
+ Uninstall: just UNINSTALL
+Update package (change the source codes and Run As again), there are four scenarios:
+1. UPDATE
+ Source code change
+2. UNINSTALL -> INSTALL
+ This happens when Tizen IDE Property > Tizen SDK > Rapid Development Support > Check "Enable Project specific settings"
+ and change Application ID in tizen-manifest.xml file and Run As.
+3. UPDATE -> INSTALL
+ This happens when Tizen IDE Property > Tizen SDK > Rapid Development Support > Uncheck "Enable Project specific settings"
+ and change Application ID in tizen-manifest.xml file and Run As.
+ At UPDATE event, pkgid (package parameter) is invalid...
+4. UPDATE
+ Exceptionally, only UPDATE can be called when Application ID in tizen-manifest.xml file is changed.
+ At UPDATE event, pkgid (package parameter) is valid, and only appid is changed; the previous appid is invalid.
+*/
+static void _package_manager_event_cb(const char *type, const char *package, package_manager_event_type_e event_type, package_manager_event_state_e event_state, int progress, package_manager_error_e error, void *user_data)
+{
+ CServiceMain* service_main = static_cast<CServiceMain*>(user_data);
+
+ int ret = 0;
+ uid_t uid = getuid();
+ pkgmgrinfo_pkginfo_h handle = NULL;
+ static bool in_progress = false;
+ bool should_exit = false;
+
+ if (!package || !type)
+ return;
+
+ if (PACKAGE_MANAGER_EVENT_TYPE_UPDATE != event_type &&
+ PACKAGE_MANAGER_EVENT_TYPE_INSTALL != event_type &&
+ PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL != event_type)
+ return;
+
+ if (PACKAGE_MANAGER_EVENT_STATE_STARTED != event_state &&
+ PACKAGE_MANAGER_EVENT_STATE_COMPLETED != event_state)
+ return;
+
+ bool user = false;
+ MAS_LOGD("type=%s package=%s event_type=%d event_state=%d progress=%d error=%d",
+ type, package, event_type, event_state, progress, error);
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle);
+ if (ret != PMINFO_R_OK || NULL == handle) {
+ MAS_LOGW("Failed to call pkgmgrinfo_pkginfo_get_pkginfo(\"%s\",~) returned %d", package, ret);
+ /* Try to get in user packages */
+ user = true;
+ ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(package, uid, &handle);
+ if (ret != PMINFO_R_OK || NULL == handle) {
+ MAS_LOGW("Failed to call pkgmgrinfo_pkginfo_get_pkginfo & get_usr_pkginfo(\"%s\",~) returned %d, uid : %d", package, ret, getuid());
+ return;
+ }
+ }
+
+ if (user) {
+ /* Try to get in user packages */
+ pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, pkg_app_list_cb, (void *)&ret, uid);
+ } else {
+ /* Try to get in global packages */
+ pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP, pkg_app_list_cb, (void *)&ret);
+ }
+ if (1 == ret) {
+ if (PACKAGE_MANAGER_EVENT_STATE_STARTED == event_state) {
+ MAS_LOGI("processing PACKAGE_MANAGER_EVENT_STATE_STARTED event : %d", event_type);
+ if (false == in_progress) {
+ in_progress = true;
+ if (service_main) {
+ service_main->deinitialize_service_plugin();
+ } else {
+ MAS_LOGE("service_main is NULL");
+ }
+ }
+ } else if (PACKAGE_MANAGER_EVENT_STATE_COMPLETED == event_state) {
+ MAS_LOGI("processing PACKAGE_MANAGER_EVENT_STATE_COMPLETED event : %d", event_type);
+ if (false == in_progress) {
+ if (service_main) {
+ service_main->deinitialize_service_plugin();
+ } else {
+ MAS_LOGE("service_main is NULL");
+ }
+ }
+ /*
+ if (service_main) {
+ service_main->initialize_service_plugin();
+ service_main->process_activated_setting();
+ } else {
+ MAS_LOGE("service_main is NULL");
+ }
+ */
+ should_exit = true;
+ in_progress = false;
+ }
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+ if (should_exit) {
+ LOGI("Now restarting multi-assistant-service for reloading updated modules");
+ service_app_exit();
+ }
+
+ return;
+}
+
+bool CServiceMain::app_create(void *data)
+{
+ // Todo: add your code here.
+ MAS_LOGD("[Enter] Service app create");
+
+ g_service_main = this;
+
+ mClientManager.set_application_manager(&mApplicationManager);
+
+ mServiceIpc.set_client_manager(&mClientManager);
+ mServiceIpc.set_service_ipc_observer(this);
+
+ mServicePlugin.set_service_ipc(&mServiceIpc);
+ mServicePlugin.set_service_main(this);
+
+ int ret = mServiceIpc.open_connection();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to open connection");
+ }
+
+ initialize_service_plugin();
+
+ 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 */
+ boost::optional<std::string> preprocessing_assistant =
+ mPreferenceManager.get_string(WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID);
+ if (preprocessing_assistant) {
+ MAS_LOGD("prelaunching preprocessing_assistant_appid : %s", (*preprocessing_assistant).c_str());
+ mas_launch_client_by_appid((*preprocessing_assistant).c_str(), CLIENT_LAUNCH_MODE_PRELAUNCH);
+ }
+
+ if (!mPackageManagerHandle) {
+ int ret = package_manager_create(&mPackageManagerHandle);
+ if (ret == PACKAGE_MANAGER_ERROR_NONE) {
+ ret = package_manager_set_event_cb(mPackageManagerHandle, _package_manager_event_cb, this);
+ if (ret == PACKAGE_MANAGER_ERROR_NONE) {
+ LOGD("package_manager_set_event_cb succeeded.");
+ } else {
+ LOGE("package_manager_set_event_cb failed(%d)", ret);
+ }
+ } else {
+ LOGE("package_manager_create failed(%d)", ret);
+ }
+ }
+
+ return true;
+}
+
+void CServiceMain::app_terminate(void *data)
+{
+ MAS_LOGI("[ENTER]");
+ if (mPackageManagerHandle) {
+ package_manager_unset_event_cb(mPackageManagerHandle);
+ package_manager_destroy(mPackageManagerHandle);
+ mPackageManagerHandle = NULL;
+ }
+
+ deinitialize_service_plugin();
+
+ mPreferenceManager.unregister_changed_callback(
+ MULTI_ASSISTANT_SETTINGS_ACTIVATED, active_state_changed_cb);
+
+ int ret = mServiceIpc.close_connection();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to close connection");
+ }
+
+ g_service_main = nullptr;
+
+ MAS_LOGI("[END]");
+ return;
+}
+
+int CServiceMain::on_initialize(int pid) {
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ std::string pid_appid;
+ boost::optional<std::string> appid_by_pid = mApplicationManager.get_appid_by_pid(pid);
+ if (appid_by_pid) {
+ pid_appid = *appid_by_pid;
+ MAS_LOGD("appid for pid %d is : %s", pid, pid_appid.c_str());
+
+ /* Remove existing client that has same appid, if there's any */
+ mClientManager.destroy_client_by_appid(pid_appid.c_str());
+
+ /* And remove a client that has same pid also */
+ mClientManager.destroy_client_by_pid(pid);
+
+ mClientManager.create_client(pid, pid_appid.c_str());
+
+ const char *current_maclient_appid = NULL;
+ if (mCurrentClientInfo >= 0 && mCurrentClientInfo < MAX_MACLIENT_INFO_NUM) {
+ current_maclient_appid = mClientInfo[mCurrentClientInfo].appid;
+ }
+
+ mas_client_send_preprocessing_information(pid);
+ if (MA_VOICE_KEY_STATUS_PRESSED == mLastVoiceKeyStatus) {
+ mas_client_send_voice_key_status_change(pid, mLastVoiceKeyStatus);
+ }
+ if (current_maclient_appid && 0 == pid_appid.compare(current_maclient_appid)) {
+ MAS_LOGD("MA client with current maclient appid connected!");
+
+ if (0 == mWakeupClientAppId.compare(pid_appid)) {
+ mWakeupClientAppId.clear();
+ mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_ACTIVE);
+ mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
+ } else {
+ MAS_LOGE("[ERROR] mWakeupClientAppId and appid differ : %s %s",
+ mWakeupClientAppId.c_str(), pid_appid.c_str());
+ }
+ } else {
+ MAS_LOGD("MA client connected, but its appid does not match with current maclient");
+ }
+
+ mServiceIpc.change_service_state(pid, mas_get_current_service_state());
+ } else {
+ MAS_LOGE("[ERROR] Fail to retrieve appid");
+ }
+
+ return 0;
+}
+
+int CServiceMain::on_deinitialize(int pid) {
+ MAS_LOGD("[Enter] pid(%d)", pid);
+ mClientManager.destroy_client_by_pid(pid);
+ return 0;
+}
+
+int CServiceMain::on_get_audio_format(int pid, int& rate, int& channel, int& audio_type) {
+ int main_rate, main_channel, main_audio_type;
+ int ret = mas_client_get_audio_format(pid,
+ &main_rate, &main_channel, &main_audio_type);
+ rate = main_rate;
+ channel = main_channel;
+ audio_type = main_audio_type;
+ return ret;
+}
+
+int CServiceMain::on_get_audio_source_type(int pid, std::string& type) {
+ char *main_type = nullptr;
+ int ret = mas_client_get_audio_source_type(pid, &main_type);
+ if (0 == ret && main_type) {
+ type = std::string{main_type};
+ }
+ return ret;
+}
+
+int CServiceMain::on_send_asr_result(int pid, int event, std::string asr_result) {
+ return mas_client_send_asr_result(pid, event, asr_result.c_str());
+}
+
+int CServiceMain::on_send_result(int pid, std::string display_text,
+ std::string utterance_text, std::string result_json) {
+ return mas_client_send_result(pid,
+ display_text.c_str(), utterance_text.c_str(), result_json.c_str());
+}
+
+int CServiceMain::on_send_recognition_result(int pid, int result) {
+ return mas_client_send_recognition_result(pid, result);
+}
+
+int CServiceMain::on_start_streaming_audio_data(int pid, int type) {
+ return mas_client_start_streaming_audio_data(pid, type);
+}
+
+int CServiceMain::on_stop_streaming_audio_data(int pid, int type) {
+ return mas_client_stop_streaming_audio_data(pid, type);
+}
+
+int CServiceMain::on_update_voice_feedback_state(int pid, int state) {
+ return mas_client_update_voice_feedback_state(pid, state);
+}
+
+int CServiceMain::on_send_assistant_specific_command(int pid, std::string command) {
+ return mas_client_set_assistant_specific_command(pid, command.c_str());
+}
+
+int CServiceMain::on_set_background_volume(int pid, double ratio) {
+ return mas_client_set_background_volume(pid, ratio);
+}
+
+int CServiceMain::on_set_preprocessing_allow_mode(int pid, int mode, std::string app_id) {
+ return mas_client_set_preprocessing_allow_mode(pid,
+ static_cast<ma_preprocessing_allow_mode_e>(mode), app_id.c_str());
+}
+
+int CServiceMain::on_send_preprocessing_result(int pid, int result) {
+ return mas_client_send_preprocessing_result(pid, result);
+}
+
+int CServiceMain::on_set_wake_word_audio_require_flag(int pid, int require) {
+ return mas_client_set_wake_word_audio_require_flag(pid, require);
+}
+
+int CServiceMain::on_set_assistant_language(int pid, std::string language) {
+ return mas_client_set_assistant_language(pid, language.c_str());
+}
+
+int CServiceMain::on_add_wake_word(int pid, std::string wake_word, std::string language) {
+ return mas_client_add_wake_word(pid, wake_word.c_str(), language.c_str());
+}
+
+int CServiceMain::on_remove_wake_word(int pid, std::string wake_word, std::string language) {
+ return mas_client_remove_wake_word(pid, wake_word.c_str(), language.c_str());
+}
+
+int CServiceMain::on_ui_initialize(int pid)
+{
+ return mas_ui_client_initialize(pid);
+}
+
+int CServiceMain::on_ui_deinitialize(int pid)
+{
+ return mas_ui_client_deinitialize(pid);
+}
+
+int CServiceMain::on_ui_change_assistant(std::string app_id)
+{
+ return mas_ui_client_change_assistant(app_id.c_str());
+}
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <tizen.h>
+#include <service_app.h>
+#include <app_manager.h>
+#include <app.h>
+#include <malloc.h>
+#include <Ecore.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <dlfcn.h>
+#include <new>
+
+#include "service_main.h"
+#include "service_plugin.h"
+#include "service_ipc_dbus.h"
+
+/* Sound buf save for test */
+#if 0
+#define BUF_SAVE_MODE
+#endif
+
+typedef struct {
+ void* data;
+ CServicePlugin* plugin;
+} AsyncParam;
+
+bool CServicePlugin::is_ui_panel_enabled()
+{
+ /* By default we assume the ui panel is always enabled unless explicitly turned off */
+ bool ret = true;
+ if (mPluginSettings) {
+ ret = mPluginSettings->ui_panel_enabled;
+ }
+ MAS_LOGD("UI Panel Enabled : %d", ret);
+ return ret;
+}
+
+#if 0 /* + TEST_CODE */
+Eina_Bool __send_asr_result(void *data)
+{
+ MAS_LOGD("[ENTER]");
+
+ if (!strcmp((char*)data, "Today's")) {
+ masc_ui_dbus_send_asr_result(-1, 1, "Today's");
+ }
+ if (!strcmp((char*)data, "weather.")) {
+ masc_ui_dbus_send_asr_result(-1, 0, "Today's weather.");
+ }
+
+ MAS_LOGD("END");
+ return EINA_FALSE;
+}
+
+Eina_Bool __send_result(void *data)
+{
+ MAS_LOGD("[ENTER]");
+
+ int ret = masc_ui_dbus_send_result(-1, (const char*)data, (const char*)data, "test");
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to stop recording(%d)", ret);
+ return EINA_TRUE;
+ }
+
+ MAS_LOGD("END");
+ return EINA_FALSE;
+}
+#endif /* -TEST_CODE */
+
+static Eina_Bool process_wakeup_event_by_appid_timer(void* data)
+{
+ if (NULL == data) return ECORE_CALLBACK_CANCEL;
+ AsyncParam* param = static_cast<AsyncParam*>(data);
+
+ char* appid = static_cast<char*>(param->data);
+ MAS_LOGD("[ENTER] appid(%s)", appid);
+
+ int pid = -1;
+ if (!appid) return ECORE_CALLBACK_CANCEL;
+
+ CServicePlugin* plugin = param->plugin;
+ CServiceIpcDbus* service_ipc = nullptr;
+ CServiceMain* service_main = nullptr;
+ if (plugin) {
+ service_ipc = plugin->get_service_ipc();
+ service_main = plugin->get_service_main();
+ }
+ if (service_ipc && service_main) {
+ bool use_custom_ui = service_main->mas_get_client_custom_ui_option_by_appid(appid);
+ bool ui_panel_enabled = false;
+ if (param->plugin) ui_panel_enabled = param->plugin->is_ui_panel_enabled();
+ if (ui_panel_enabled) {
+ service_ipc->masc_ui_dbus_enable_common_ui(!use_custom_ui);
+ service_ipc->masc_ui_dbus_change_assistant(appid);
+ }
+
+ service_main->mas_set_current_client_by_appid(appid);
+ if ((pid = service_main->mas_get_client_pid_by_appid(appid)) != -1) {
+ service_main->mas_client_send_preprocessing_information(pid);
+ service_ipc->change_active_state(pid, MA_ACTIVE_STATE_ACTIVE);
+ service_main->mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
+ } else {
+ // Appropriate MA Client not available, trying to launch new one
+ MAS_LOGD("MA Client with appid %s does not exist, launching client", appid);
+ service_main->mas_launch_client_by_appid(appid, CLIENT_LAUNCH_MODE_ACTIVATION);
+ }
+ }
+
+ if (appid) free(appid);
+ delete param;
+
+ MAS_LOGD("END");
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool process_wakeup_event_by_word_timer(void* data)
+{
+ MAS_LOGD("[ENTER]");
+
+ if (NULL == data) return ECORE_CALLBACK_CANCEL;
+ AsyncParam* param = static_cast<AsyncParam*>(data);
+
+ char* wakeup_word = static_cast<char*>(param->data);
+ CServicePlugin* plugin = param->plugin;
+ CServiceMain* service_main = nullptr;
+
+ if (plugin) {
+ service_main = plugin->get_service_main();
+ }
+
+ delete param;
+ param = nullptr;
+
+ if (service_main) {
+ const char* appid = service_main->mas_get_client_appid_by_wakeup_word(wakeup_word);
+ if (appid) {
+ param = new(std::nothrow) AsyncParam;
+ if (param) {
+ param->data = static_cast<void*>(strdup(appid));
+ param->plugin = plugin;
+ process_wakeup_event_by_appid_timer(static_cast<void*>(param));
+ }
+ }
+ }
+
+ if (wakeup_word) free(wakeup_word);
+
+ MAS_LOGD("END");
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void __wakeup_event_cb(mas_wakeup_event_info wakeup_info, void* user_data)
+{
+ MAS_LOGD("dalton debug : %p", user_data);
+ MAS_LOGD("[SUCCESS] __wakeup_event_cb is called, wakeup_word(%s)", wakeup_info.wakeup_word);
+ int ret = -1;
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (plugin) {
+ CServiceIpcDbus* service_ipc = plugin->get_service_ipc();
+ if (plugin->is_ui_panel_enabled() && service_ipc) {
+ int retry_cnt = 0;
+ while (0 != ret) {
+ ret = service_ipc->masc_ui_dbus_send_hello();
+ retry_cnt++;
+ if (5 < retry_cnt) {
+ MAS_LOGE("[ERROR] Fail to receive reply for hello, ret(%d)", ret);
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef BUF_SAVE_MODE
+ if (mDumpFile) {
+ fclose(mDumpFile);
+ mDumpFile = NULL;
+ } else {
+ MAS_LOGD("[Recorder Info] File not found!");
+ }
+
+ while (1) {
+ snprintf(mDumpFilename, sizeof(mDumpFilename), "/tmp/ma_service_%d_%d", getpid(), mDumpCount);
+ int ret = access(mDumpFilename, 0);
+
+ if (0 == ret) {
+ MAS_LOGD("[Recorder ERROR] File is already exist");
+ if (0 == remove(mDumpFilename)) {
+ MAS_LOGD("[Recorder] Remove file");
+ break;
+ } else {
+ mDumpCount++;
+ }
+ } else {
+ break;
+ }
+ }
+
+ MAS_LOGD("[Recorder] Temp file name=[%s]", mDumpFilename);
+
+ /* open test file */
+ mDumpFile = fopen(mDumpFilename, "wb+x");
+ if (!mDumpFile) {
+ MAS_LOGD("[Recorder ERROR] File not found!");
+ return;
+ }
+ mDumpCount++;
+#endif
+
+#if 0 /* + TEST_CODE */
+ if (WAKEUP_EVENT_SUCCESS == event) {
+ ecore_thread_main_loop_begin();
+ ecore_timer_add(1.0, __send_asr_result, "Today's");
+ ecore_thread_main_loop_end();
+
+ ecore_thread_main_loop_begin();
+ ecore_timer_add(2.0, __send_asr_result, "weather.");
+ ecore_thread_main_loop_end();
+
+ ecore_thread_main_loop_begin();
+ ecore_timer_add(3.0, __send_result, "Partly cloudy with temperatures from 75 to 88");
+ ecore_thread_main_loop_end();
+ }
+#endif /* - TEST_CODE */
+ if (wakeup_info.wakeup_appid) {
+ AsyncParam* param = new(std::nothrow) AsyncParam;
+ if (param) {
+ param->data = static_cast<void*>(strdup(wakeup_info.wakeup_appid));
+ param->plugin = static_cast<CServicePlugin*>(user_data);
+ ecore_thread_main_loop_begin();
+ ecore_timer_add(0.0f, process_wakeup_event_by_appid_timer,
+ static_cast<void*>(param));
+ ecore_thread_main_loop_end();
+ }
+ } else if (wakeup_info.wakeup_word) {
+ AsyncParam* param = new(std::nothrow) AsyncParam;
+ if (param) {
+ param->data = static_cast<void*>(strdup(wakeup_info.wakeup_word));
+ param->plugin = static_cast<CServicePlugin*>(user_data);
+ ecore_thread_main_loop_begin();
+ ecore_timer_add(0.0f, process_wakeup_event_by_word_timer,
+ static_cast<void*>(param));
+ ecore_thread_main_loop_end();
+ }
+ }
+}
+
+static bool __validate_streaming_event_order(int pid, mas_speech_streaming_event_e *event)
+{
+ bool ret = false;
+
+ static int previous_pid = -1;
+ static mas_speech_streaming_event_e previous_event = MAS_SPEECH_STREAMING_EVENT_FINISH;
+
+ if (NULL == event) return false;
+
+ mas_speech_streaming_event_e expected_sequence[][2] = {
+ {MAS_SPEECH_STREAMING_EVENT_START, MAS_SPEECH_STREAMING_EVENT_CONTINUE},
+ {MAS_SPEECH_STREAMING_EVENT_START, MAS_SPEECH_STREAMING_EVENT_FINISH},
+ {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) {
+ /* When sending streaming event to a new client, it always sends START message first */
+ previous_event = MAS_SPEECH_STREAMING_EVENT_FINISH;
+ }
+
+ for (int loop = 0;loop < sizeof(expected_sequence) / sizeof(expected_sequence[0]);loop++) {
+ if (previous_event == expected_sequence[loop][0] &&
+ *event == expected_sequence[loop][1]) {
+ ret = true;
+ }
+ }
+ if (!ret) {
+ /* In case of FINISH -> CONTINUE without START, simply modify current event value */
+ if (MAS_SPEECH_STREAMING_EVENT_FINISH == previous_event &&
+ MAS_SPEECH_STREAMING_EVENT_CONTINUE == *event) {
+ *event = MAS_SPEECH_STREAMING_EVENT_START;
+ ret = true;
+
+ MAS_LOGD("[WARNING] forcibly changed CONTINUE to START : %d -> %d (PID %d -> %d)",
+ previous_event, *event, previous_pid, pid);
+ }
+ }
+
+ if (ret) {
+ previous_pid = pid;
+ previous_event = *event;
+ } else {
+ MAS_LOGE("[ERROR] State sequence validation failed : %d -> %d (PID %d -> %d)",
+ previous_event, *event, previous_pid, pid);
+ }
+ return ret;
+}
+
+void handle_speech_streaming_event_failure(void* data)
+{
+ AsyncParam* param = static_cast<AsyncParam*>(data);
+ if (NULL == param) return;
+
+ CServicePlugin* plugin = param->plugin;
+ CServiceMain* service_main = nullptr;
+ if (plugin) service_main = plugin->get_service_main();
+
+ if (service_main) {
+ service_main->mas_client_send_recognition_result(0, MA_RECOGNITION_RESULT_EVENT_ERROR);
+ }
+
+ delete param;
+}
+
+static void __audio_streaming_cb(mas_speech_streaming_event_e event, void* buffer, int len, void *user_data)
+{
+ if (event == MAS_SPEECH_STREAMING_EVENT_FAIL) {
+ ecore_main_loop_thread_safe_call_async(handle_speech_streaming_event_failure, NULL);
+ return;
+ }
+ static int count = 0;
+ if (event != MAS_SPEECH_STREAMING_EVENT_CONTINUE || count % 100 == 0) {
+ MAS_LOGD("[SUCCESS] __audio_streaming_cb is called, event(%d), buffer(%p), len(%d)",
+ event, buffer, len);
+ }
+ ++count;
+
+ CServicePlugin* plugin = static_cast<CServicePlugin*>(user_data);
+ CServiceIpcDbus* service_ipc = nullptr;
+ CServiceMain* service_main = nullptr;
+ if (plugin) {
+ service_ipc = plugin->get_service_ipc();
+ service_main = plugin->get_service_main();
+ }
+
+ if (service_ipc && service_main) {
+ int pid = service_main->mas_get_current_client_pid();
+ int preprocessing_pid = service_main->mas_get_current_preprocessing_client_pid();
+ if (pid == -1) {
+ MAS_LOGE("[ERROR] Fail to retrieve pid of current MA client");
+ } else {
+ if (__validate_streaming_event_order(pid, &event)) {
+ int ret = service_ipc->send_streaming_audio_data(pid,
+ event, buffer, len);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send speech data, ret(%d)", ret);
+ }
+ if (pid != preprocessing_pid && -1 != preprocessing_pid) {
+ int ret = service_ipc->send_streaming_audio_data(preprocessing_pid,
+ event, buffer, len);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send speech data to preprocessing client, ret(%d)", ret);
+ }
+ }
+ }
+ }
+ }
+#ifdef BUF_SAVE_MODE
+ if (mDumpFile)
+ fwrite(speech_data->buffer, 1, speech_data->len, mDumpFile);
+
+ if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
+ if (mDumpFile) {
+ MAS_LOGE("[Recorder SUCCESS] File Close");
+ fclose(mDumpFile);
+ mDumpFile = NULL;
+ } else {
+ MAS_LOGE("[Recorder ERROR] File not found!");
+ }
+ }
+#endif
+}
+
+static void __speech_status_cb(mas_speech_status_e status, void *user_data)
+{
+ MAS_LOGD("[SUCCESS] __speech_status_cb is called, status(%d)", status);
+}
+
+static void __error_cb(int error, const char* err_msg, void* user_data)
+{
+ MAS_LOGD("[SUCCESS] __error_cb is called, error(%d), err_msg(%s)", error, err_msg);
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceIpcDbus* service_ipc = plugin->get_service_ipc();
+ if (plugin->is_ui_panel_enabled() && service_ipc) {
+ int ret = service_ipc->masc_ui_dbus_send_error_message(error, err_msg);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send error message, ret(%d)", ret);
+ }
+ }
+}
+
+static void __setting_changed_cb(void *user_data)
+{
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceMain* service_main = plugin->get_service_main();
+ if (service_main) {
+ service_main->mas_prelaunch_default_assistant();
+ service_main->mas_update_voice_key_support_mode();
+ }
+ MAS_LOGD("[SUCCESS] __setting_changed_cb is called");
+}
+
+static void __streaming_section_changed_cb(ma_audio_streaming_data_section_e section, void* user_data)
+{
+ MAS_LOGD("[SUCCESS] __streaming_section_changed_cb is called, section(%d)", section);
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceIpcDbus *service_ipc = plugin->get_service_ipc();
+ CServiceMain* service_main = plugin->get_service_main();
+ if (service_ipc && service_main) {
+ int pid = service_main->mas_get_current_client_pid();
+ int ret = service_ipc->send_streaming_section_changed(pid, (int)section);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send streaming section changed information, ret(%d)", ret);
+ }
+ }
+}
+
+static void __wakeup_engine_command_cb(mas_wakeup_engine_command_target_e target, const char* assistant_name, const char* command, void* user_data)
+{
+ MAS_LOGD("[SUCCESS] __wakeup_engine_command_cb is called, command(%s)", command);
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceIpcDbus *service_ipc = plugin->get_service_ipc();
+ CServiceMain* service_main = plugin->get_service_main();
+ if (service_ipc && service_main) {
+ int pid = service_main->mas_get_client_pid_by_appid(assistant_name);
+ if (-1 != pid) {
+ int ret = service_ipc->send_wakeup_engine_command(pid, command);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send wakeup engine command, ret(%d)", ret);
+ }
+ }
+ }
+}
+
+static void __wakeup_service_state_changed_cb(ma_service_state_e state, void* user_data)
+{
+ MAS_LOGD("[SUCCESS] __wakeup_service_state_changed_cb is called, state(%d)", state);
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceMain* service_main = plugin->get_service_main();
+ if (service_main) {
+ service_main->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);
+
+ CServicePlugin *plugin = static_cast<CServicePlugin*>(user_data);
+ if (nullptr == plugin) return;
+
+ CServiceIpcDbus *service_ipc = plugin->get_service_ipc();
+ CServiceMain* service_main = plugin->get_service_main();
+ if (service_ipc && service_main) {
+ int pid = service_main->mas_get_current_client_pid();
+ int ret = service_ipc->change_voice_key_status(pid, status);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to send voice key status changed information, ret(%d)", ret);
+ }
+ }
+}
+
+int CServicePlugin::initialize(void)
+{
+ MAS_LOGD("[Enter]");
+
+ char filepath[512] = {'\0', };
+ const char *default_engine_path = MA_WAKEUP_MANAGER_PATH;
+ snprintf(filepath, 512, "%s/%s", default_engine_path, MA_DEFAULT_WAKEUP_MANAGER_FILENAME);
+
+ char *error;
+ mPluginHandle = NULL;
+ mPluginHandle = dlopen(filepath, RTLD_LAZY);
+ if (NULL != (error = dlerror())) {
+ MAS_LOGE("[ERROR] Fail to dlopen(%s), error(%s)", filepath, error);
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ mWakeupManagerInterface.initialize =
+ (wakeup_manager_initialize)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_INITIALIZE);
+ mWakeupManagerInterface.deinitialize =
+ (wakeup_manager_deinitialize)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE);
+ mWakeupManagerInterface.get_settings =
+ (wakeup_manager_get_settings)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
+ mWakeupManagerInterface.add_assistant_wakeup_word =
+ (wakeup_manager_add_assistant_wakeup_word)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_WAKEUP_WORD);
+ mWakeupManagerInterface.remove_assistant_wakeup_word =
+ (wakeup_manager_remove_assistant_wakeup_word)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_REMOVE_ASSISTANT_WAKEUP_WORD);
+ mWakeupManagerInterface.add_assistant_language =
+ (wakeup_manager_add_assistant_language)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE);
+ mWakeupManagerInterface.set_assistant_wakeup_engine =
+ (wakeup_manager_set_assistant_wakeup_engine)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_WAKEUP_ENGINE);
+ mWakeupManagerInterface.set_default_assistant =
+ (wakeup_manager_set_default_assistant)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_DEFAULT_ASSISTANT);
+ mWakeupManagerInterface.get_default_assistant =
+ (wakeup_manager_get_default_assistant)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_GET_DEFAULT_ASSISTANT);
+ mWakeupManagerInterface.set_language =
+ (wakeup_manager_set_language)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE);
+ mWakeupManagerInterface.activate =
+ (wakeup_manager_activate)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_ACTIVATE);
+ mWakeupManagerInterface.deactivate =
+ (wakeup_manager_deactivate)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_DEACTIVATE);
+ mWakeupManagerInterface.update_voice_feedback_state =
+ (wakeup_manager_update_voice_feedback_state)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE);
+ mWakeupManagerInterface.set_assistant_specific_command =
+ (wakeup_manager_set_assistant_specific_command)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_SPECIFIC_COMMAND);
+ mWakeupManagerInterface.set_background_volume =
+ (wakeup_manager_set_background_volume)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_BACKGROUND_VOLUME);
+ mWakeupManagerInterface.update_recognition_result =
+ (wakeup_manager_update_recognition_result)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_UPDATE_RECOGNITION_RESULT);
+ mWakeupManagerInterface.process_plugin_event =
+ (wakeup_manager_process_plugin_event)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_PROCESS_PLUGIN_EVENT);
+ mWakeupManagerInterface.start_streaming_utterance_data =
+ (wakeup_manager_start_streaming_utterance_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA);
+ mWakeupManagerInterface.stop_streaming_utterance_data =
+ (wakeup_manager_stop_streaming_utterance_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA);
+ mWakeupManagerInterface.start_streaming_previous_utterance_data =
+ (wakeup_manager_start_streaming_previous_utterance_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA);
+ mWakeupManagerInterface.stop_streaming_previous_utterance_data =
+ (wakeup_manager_stop_streaming_previous_utterance_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA);
+ mWakeupManagerInterface.start_streaming_follow_up_data =
+ (wakeup_manager_start_streaming_follow_up_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA);
+ mWakeupManagerInterface.stop_streaming_follow_up_data =
+ (wakeup_manager_stop_streaming_follow_up_data)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA);
+ mWakeupManagerInterface.get_audio_format =
+ (wakeup_manager_get_audio_format)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT);
+ mWakeupManagerInterface.get_audio_source_type =
+ (wakeup_manager_get_audio_source_type)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_SOURCE_TYPE);
+ mWakeupManagerInterface.set_wake_word_audio_require_flag =
+ (wakeup_manager_set_wake_word_audio_require_flag)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG);
+ mWakeupManagerInterface.set_assistant_language =
+ (wakeup_manager_set_assistant_language)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_LANGUAGE);
+ mWakeupManagerInterface.set_voice_key_tap_duration =
+ (wakeup_manager_set_voice_key_tap_duration)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_TAP_DURATION);
+ mWakeupManagerInterface.unset_voice_key_tap_duration =
+ (wakeup_manager_unset_voice_key_tap_duration)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_UNSET_VOICE_KEY_TAP_DURATION);
+ mWakeupManagerInterface.set_voice_key_support_mode =
+ (wakeup_manager_set_voice_key_support_mode)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_SUPPORT_MODE);
+ mWakeupManagerInterface.set_wakeup_event_callback =
+ (wakeup_manager_set_wakeup_event_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK);
+ mWakeupManagerInterface.set_utterance_streaming_callback =
+ (wakeup_manager_set_utterance_streaming_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK);
+ mWakeupManagerInterface.set_previous_utterance_streaming_callback =
+ (wakeup_manager_set_previous_utterance_streaming_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK);
+ mWakeupManagerInterface.set_follow_up_streaming_callback =
+ (wakeup_manager_set_follow_up_streaming_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK);
+ mWakeupManagerInterface.set_speech_status_callback =
+ (wakeup_manager_set_speech_status_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK);
+ mWakeupManagerInterface.set_setting_changed_callback =
+ (wakeup_manager_set_setting_changed_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_SETTING_CHANGED_CALLBACK);
+ mWakeupManagerInterface.set_error_callback =
+ (wakeup_manager_set_error_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK);
+ mWakeupManagerInterface.set_streaming_section_changed_callback =
+ (wakeup_manager_set_streaming_section_changed_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_STREAMING_SECTION_CHANGED_CALLBACK);
+ mWakeupManagerInterface.set_wakeup_engine_command_callback =
+ (wakeup_manager_set_wakeup_engine_command_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_ENGINE_COMMAND_CALLBACK);
+ mWakeupManagerInterface.set_wakeup_service_state_changed_callback =
+ (wakeup_manager_set_wakeup_service_state_changed_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_SERVICE_STATE_CHANGED_CALLBACK);
+ mWakeupManagerInterface.set_voice_key_status_changed_callback =
+ (wakeup_manager_set_voice_key_status_changed_callback)dlsym(mPluginHandle,
+ MA_WAKEUP_MANAGER_FUNC_SET_VOICE_KEY_STATUS_CHANGED_CALLBACK);
+
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_initialize func = mWakeupManagerInterface.initialize;
+
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_INITIALIZE);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to initialize, ret(%d)", ret);
+ }
+ }
+
+ wakeup_manager_get_settings get_settings_func = mWakeupManagerInterface.get_settings;
+
+ if (NULL == get_settings_func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
+ } else {
+ size_t struct_size;
+ ret = get_settings_func(&mPluginSettings, &struct_size);
+ if (0 != ret || struct_size != sizeof(ma_plugin_settings)) {
+ MAS_LOGE("[ERROR] Fail to get settings, ret(%d), size %zu", ret, struct_size);
+ mPluginSettings = NULL;
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::deinitialize(void)
+{
+#ifdef BUF_SAVE_MODE
+ if (mDumpFile) {
+ fclose(mDumpFile);
+ mDumpFile = NULL;
+ } else {
+ MAS_LOGD("[Recorder ERROR] File not found!");
+ }
+#endif
+
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_deinitialize func = mWakeupManagerInterface.deinitialize;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to deinitialize, ret(%d)", ret);
+ }
+ }
+
+ dlclose(mPluginHandle);
+ mPluginHandle = NULL;
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+
+ return ret;
+}
+
+int CServicePlugin::get_settings(ma_plugin_settings **settings, size_t *struct_size)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_get_settings func = mWakeupManagerInterface.get_settings;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_SETTINGS);
+ } else {
+ ret = func(settings, struct_size);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to get settings, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_language(const char* language)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_language func = mWakeupManagerInterface.set_language;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE);
+ } else {
+ ret = func(language);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set langauge(%s), ret(%d)", language, ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::add_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_add_assistant_wakeup_word func = mWakeupManagerInterface.add_assistant_wakeup_word;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_WAKEUP_WORD);
+ } else {
+ ret = func(appid, wakeup_word, language);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to add wakeup word(%s)(%s)(%s), ret(%d)", appid, wakeup_word, language, ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::remove_assistant_wakeup_word(const char* appid, const char* wakeup_word, const char* language)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_remove_assistant_wakeup_word func = mWakeupManagerInterface.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 {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::add_assistant_language(const char* appid, const char* language)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_add_assistant_language func = mWakeupManagerInterface.add_assistant_language;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ADD_ASSISTANT_LANGUAGE);
+ } else {
+ ret = func(appid, language);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set wakeup word(%s)(%s), ret(%d)", appid, language, ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_assistant_wakeup_engine(const char* appid, const char* engine)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_assistant_wakeup_engine func = mWakeupManagerInterface.set_assistant_wakeup_engine;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_WAKEUP_ENGINE);
+ } else {
+ ret = func(appid, engine);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set wakeup engine(%s)(%s), ret(%d)", appid, engine, ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_default_assistant(const char* appid)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_default_assistant func = mWakeupManagerInterface.set_default_assistant;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_DEFAULT_ASSISTANT);
+ } else {
+ ret = func(appid);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set default assistant(%s), ret(%d)", appid, ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::get_default_assistant(const char** appid)
+{
+ int ret = -1;
+ if (NULL == appid) {
+ MAS_LOGE("[ERROR] appid is not valid");
+ return ret;
+ }
+ if (NULL != mPluginHandle) {
+ wakeup_manager_get_default_assistant func = mWakeupManagerInterface.get_default_assistant;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_DEFAULT_ASSISTANT);
+ } else {
+ ret = func(appid);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to get default assistant, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::activate(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_activate func = mWakeupManagerInterface.activate;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ACTIVATE);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to start recording, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::deactivate(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_deactivate func = mWakeupManagerInterface.deactivate;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEACTIVATE);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::update_voice_feedback_state(const char* appid, int state)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_update_voice_feedback_state func = mWakeupManagerInterface.update_voice_feedback_state;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE);
+ } else {
+ ret = func(appid, state);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_assistant_specific_command(const char* appid, const char* command)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_assistant_specific_command func = mWakeupManagerInterface.set_assistant_specific_command;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_SPECIFIC_COMMAND);
+ } else {
+ ret = func(appid, command);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_background_volume(const char* appid, double ratio)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_background_volume func = mWakeupManagerInterface.set_background_volume;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_BACKGROUND_VOLUME);
+ } else {
+ ret = func(appid, ratio);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set background volume, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::update_recognition_result(const char* appid, int state)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_update_recognition_result func = mWakeupManagerInterface.update_recognition_result;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_RECOGNITION_RESULT);
+ } else {
+ ret = func(appid, state);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to update result state, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::process_event(int event, void *data, int len)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_process_plugin_event func = mWakeupManagerInterface.process_plugin_event;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_PROCESS_PLUGIN_EVENT);
+ } else {
+ ret = func((mas_plugin_event_e)event, data, len);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::start_streaming_utterance_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_start_streaming_utterance_data func = mWakeupManagerInterface.start_streaming_utterance_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::stop_streaming_utterance_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_stop_streaming_utterance_data func = mWakeupManagerInterface.stop_streaming_utterance_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::start_streaming_previous_utterance_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_start_streaming_previous_utterance_data func = mWakeupManagerInterface.start_streaming_previous_utterance_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request previous speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::stop_streaming_previous_utterance_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_stop_streaming_previous_utterance_data func = mWakeupManagerInterface.stop_streaming_previous_utterance_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request previous speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::start_streaming_follow_up_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_start_streaming_follow_up_data func = mWakeupManagerInterface.start_streaming_follow_up_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::stop_streaming_follow_up_data(void)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_stop_streaming_follow_up_data func = mWakeupManagerInterface.stop_streaming_follow_up_data;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA);
+ } else {
+ ret = func();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::get_recording_audio_format(int *rate, int *channel, int *audio_type)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_get_audio_format func = mWakeupManagerInterface.get_audio_format;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT);
+ } else {
+ ret = func(rate, channel, audio_type);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::get_recording_audio_source_type(char** type)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_get_audio_source_type func = mWakeupManagerInterface.get_audio_source_type;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_SOURCE_TYPE);
+ } else {
+ ret = func(type);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to get recording audio source type, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_voice_key_tap_duration(float duration)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_voice_key_tap_duration func = mWakeupManagerInterface.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] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::unset_voice_key_tap_duration()
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_unset_voice_key_tap_duration func = mWakeupManagerInterface.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] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_voice_key_support_mode(int mode)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_voice_key_support_mode func = mWakeupManagerInterface.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] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_wake_word_audio_require_flag(const char* appid, bool require)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_wake_word_audio_require_flag func = mWakeupManagerInterface.set_wake_word_audio_require_flag;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG);
+ } else {
+ ret = func(require);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set wake word audio require flag, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_assistant_language(const char* appid, const char* language)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_assistant_language func = mWakeupManagerInterface.set_assistant_language;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ASSISTANT_LANGUAGE);
+ } else {
+ ret = func(appid, language);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set assistant language, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_callbacks(void)
+{
+ int ret = set_wakeup_event_callback(__wakeup_event_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set wakeup event cb");
+ return ret;
+ }
+
+ ret = set_utterance_streaming_callback(__audio_streaming_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set utterance streaming cb");
+ return ret;
+ }
+
+ ret = set_previous_utterance_streaming_callback(__audio_streaming_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set previous utterance streaming cb");
+ return ret;
+ }
+
+ ret = set_follow_up_streaming_callback(__audio_streaming_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set follow-up streaming cb");
+ return ret;
+ }
+
+ ret = set_speech_status_callback(__speech_status_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set speech status changed cb");
+ return ret;
+ }
+
+ ret = set_setting_changed_callback(__setting_changed_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set setting changed cb");
+ return ret;
+ }
+
+ ret = set_error_callback(__error_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set error cb");
+ return ret;
+ }
+
+ ret = set_streaming_section_changed_callback(__streaming_section_changed_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set streaming section changed cb");
+ return ret;
+ }
+
+ ret = set_wakeup_engine_command_callback(__wakeup_engine_command_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set wakeup engine command cb");
+ return ret;
+ }
+
+ ret = set_wakeup_service_state_changed_callback(__wakeup_service_state_changed_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set wakeup engine command cb");
+ return ret;
+ }
+
+ ret = set_voice_key_status_changed_callback(__wakeup_service_voice_key_status_changed_cb, this);
+ if (0 != ret) {
+ MAS_LOGE("Fail to set wakeup engine command cb");
+ return ret;
+ }
+
+ return 0;
+}
+
+int CServicePlugin::set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_wakeup_event_callback func = mWakeupManagerInterface.set_wakeup_event_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ MAS_LOGD("dalton debug : %p", user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set wakeup event callback, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_utterance_streaming_callback func = mWakeupManagerInterface.set_utterance_streaming_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_previous_utterance_streaming_callback func = mWakeupManagerInterface.set_previous_utterance_streaming_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_follow_up_streaming_callback func = mWakeupManagerInterface.set_follow_up_streaming_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set follow-up streaming callback, ret(%d)", ret);
+ }
+ }
+ } else {
+ MAS_LOGE("[ERROR] mPluginHandle is not valid");
+ }
+ return ret;
+}
+
+int CServicePlugin::set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_speech_status_callback func = mWakeupManagerInterface.set_speech_status_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set speech status callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_setting_changed_callback(wakeup_service_setting_changed_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_setting_changed_callback func = mWakeupManagerInterface.set_setting_changed_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_SETTING_CHANGED_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set setting_changed callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_error_callback(wakeup_service_error_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_error_callback func = mWakeupManagerInterface.set_error_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_streaming_section_changed_callback(wakeup_service_streaming_section_changed_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_streaming_section_changed_callback func = mWakeupManagerInterface.set_streaming_section_changed_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_STREAMING_SECTION_CHANGED_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set streaming section changed callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_wakeup_engine_command_callback(wakeup_service_wakeup_engine_command_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_wakeup_engine_command_callback func = mWakeupManagerInterface.set_wakeup_engine_command_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_ENGINE_COMMAND_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_wakeup_service_state_changed_callback(wakeup_service_wakeup_service_state_changed_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_wakeup_service_state_changed_callback func = mWakeupManagerInterface.set_wakeup_service_state_changed_callback;
+ if (NULL == func) {
+ MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_SERVICE_STATE_CHANGED_CALLBACK);
+ } else {
+ ret = func(callback, user_data);
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret);
+ }
+ }
+ }
+ return ret;
+}
+
+int CServicePlugin::set_voice_key_status_changed_callback(wakeup_service_voice_key_status_changed_cb callback, void* user_data)
+{
+ int ret = -1;
+ if (NULL != mPluginHandle) {
+ wakeup_manager_set_voice_key_status_changed_callback func = mWakeupManagerInterface.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;
+}
+
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(utc)
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(config)
+ADD_SUBDIRECTORY(client-manager)
+ADD_SUBDIRECTORY(audio-manager)
+ADD_SUBDIRECTORY(service-main)
--- /dev/null
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/inc
+ )
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+
+SET(TEST_SOURCES
+ test_audio_manager.cpp
+ ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/src/wakeup_audio_manager.cpp
+ ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/src/dependency_resolver.cpp
+ ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/src/heap_tracer.cpp
+)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ capi-appfw-application
+ capi-appfw-preference
+ multi-assistant
+ dlog
+ libxml-2.0
+ capi-media-audio-io
+ vconf
+ ecore
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FIND_PACKAGE(GTest REQUIRED)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
+
+SET(TEST_AUDIO_MANAGER test-audio-manager)
+ADD_EXECUTABLE(${TEST_AUDIO_MANAGER}
+ ${TEST_SOURCES}
+ )
+
+TARGET_LINK_LIBRARIES(${TEST_AUDIO_MANAGER} -ldl ${GTEST_LIBRARIES} pthread
+ ${EXTRA_LDFLAGS} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${TEST_AUDIO_MANAGER} DESTINATION bin)
+
+ADD_TEST(NAME ${TEST_AUDIO_MANAGER} COMMAND ${TEST_AUDIO_MANAGER})
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "wakeup_audio_manager.h"
+
+#include <string>
+#include <iostream>
+
+class CAudioEventObserver : public multiassistant::wakeup::IAudioEventObserver
+{
+public:
+ virtual bool on_recording_audio_data(long time, void* data, int len) override
+ {
+ return true;
+ }
+ virtual bool on_streaming_audio_data(
+ mas_speech_streaming_event_e event, void* buffer, unsigned int len) override
+ {
+ std::string data = std::string{reinterpret_cast<const char*>(buffer), len};
+ mStreamingData.push_back(data);
+ return true;
+ }
+ std::vector<std::string> mStreamingData;
+};
+
+class DefaultFixture : public testing::Test
+{
+public:
+ DefaultFixture() {
+ }
+ virtual ~DefaultFixture() {
+ }
+ void SetUp() override {
+ }
+ void TearDown() override {
+ }
+ CAudioEventObserver mAudioEventObserver;
+ multiassistant::wakeup::CAudioManager audio_manager{&mAudioEventObserver};
+};
+
+TEST_F(DefaultFixture, StreamsAllDataFed) {
+ std::string arbitrary_data{"arbitrary_data"};
+ size_t data_feed_num = 10;
+ for (int loop = 0;loop < data_feed_num;loop++) {
+ /* CONTINUE by default */
+ mas_speech_streaming_event_e event = MAS_SPEECH_STREAMING_EVENT_CONTINUE;
+ if (0 == loop) event = MAS_SPEECH_STREAMING_EVENT_START;
+ else if (data_feed_num - 1 == loop) event = MAS_SPEECH_STREAMING_EVENT_FINISH;
+ audio_manager.feed_audio_data(event,
+ (void*)(arbitrary_data.c_str()), arbitrary_data.size());
+ }
+
+ audio_manager.streaming_audio_data_thread_func(std::numeric_limits<long>::min());
+
+ int count = 0;
+ for (std::string data : mAudioEventObserver.mStreamingData) {
+ if (0 == data.compare(arbitrary_data)) {
+ count++;
+ }
+ }
+ ASSERT_EQ(count, data_feed_num);
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}
--- /dev/null
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+
+SET(TEST_SOURCES
+ test_client_manager.cpp
+ ${CMAKE_SOURCE_DIR}/src/client_manager.cpp
+)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ capi-appfw-application
+ capi-appfw-preference
+ multi-assistant
+ dlog
+ libxml-2.0
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FIND_PACKAGE(GTest REQUIRED)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
+
+SET(TEST_CLIENT_MANAGER test-client-manager)
+ADD_EXECUTABLE(${TEST_CLIENT_MANAGER}
+ ${TEST_SOURCES}
+ )
+
+TARGET_LINK_LIBRARIES(${TEST_CLIENT_MANAGER} -ldl ${GTEST_LIBRARIES} pthread
+ ${EXTRA_LDFLAGS} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${TEST_CLIENT_MANAGER} DESTINATION bin)
+
+ADD_TEST(NAME ${TEST_CLIENT_MANAGER} COMMAND ${TEST_CLIENT_MANAGER})
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "client_manager.h"
+
+#include <string>
+
+class CDummyApplicationManager : public IApplicationManager
+{
+public:
+ CDummyApplicationManager() {};
+ virtual ~CDummyApplicationManager() {};
+
+ bool is_application_running(int pid) { return true; }
+ bool is_application_running(const std::string& appid) { return true; }
+ bool bring_app_to_foreground(const std::string& appid) { return true; }
+ bool launch_app_async(const std::string& appid, bool background) { return true; }
+ boost::optional<std::string> get_appid_by_pid(int pid) { return boost::optional<std::string>{}; }
+};
+
+class StorageWithNoClient : public testing::Test
+{
+public:
+ StorageWithNoClient() {
+ }
+ virtual ~StorageWithNoClient() {
+ }
+ void SetUp() override {
+ client_manager.set_application_manager(&application_manager);
+ }
+ void TearDown() override {
+ }
+ CClientManager client_manager;
+ CDummyApplicationManager application_manager;
+};
+
+TEST_F(StorageWithNoClient, HasOneClientAfterCreate) {
+ const std::string arbitrary_client_appid{"Client1"};
+ const int arbitrary_client_pid{1};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ int client_num = client_manager.get_client_num();
+
+ ASSERT_EQ(client_num, 1);
+}
+
+TEST_F(StorageWithNoClient, ValidityReturnsTrueForCreatedClient) {
+ const std::string arbitrary_client_appid{"Client1"};
+ const int arbitrary_client_pid{1};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ bool validity = client_manager.check_client_validity_by_appid(arbitrary_client_appid);
+
+ ASSERT_TRUE(validity);
+}
+
+TEST_F(StorageWithNoClient, ValidityReturnsFalseForNotCreatedClient) {
+ const std::string arbitrary_client_appid{"Client1"};
+ const int arbitrary_client_pid{1};
+
+ const std::string noexist_client_appid{"Client987654321"};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ bool validity = client_manager.check_client_validity_by_appid(noexist_client_appid);
+
+ ASSERT_FALSE(validity);
+}
+
+class StorageWithOneClient : public testing::Test {
+public:
+ StorageWithOneClient() {
+ }
+ virtual ~StorageWithOneClient() {
+ }
+ void SetUp() override {
+ client_manager.set_application_manager(&application_manager);
+ client_manager.create_client(preloaded_client_pid_1, preloaded_client_appid_1);
+ }
+ void TearDown() override {
+ }
+ const std::string preloaded_client_appid_1{"Client1"};
+ const int preloaded_client_pid_1{1};
+ CClientManager client_manager;
+ CDummyApplicationManager application_manager;
+};
+
+TEST_F(StorageWithOneClient, ReturnsExistingPIDByIndex) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ int pid = client_manager.find_client_pid_by_index(0);
+
+ ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCreatedPIDByIndex) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ int pid = client_manager.find_client_pid_by_index(1);
+
+ ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, PreservesExistingItemNotRequestedForRemoval) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+ client_manager.destroy_client_by_pid(arbitrary_client_pid);
+
+ int pid = client_manager.find_client_pid_by_index(0);
+
+ ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, PreservesCreatedItemNotRequestedForRemoval) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+ client_manager.destroy_client_by_pid(preloaded_client_pid_1);
+
+ int pid = client_manager.find_client_pid_by_index(0);
+
+ ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectExistingPIDByAppID) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ int pid = client_manager.find_client_pid_by_appid(preloaded_client_appid_1);
+
+ ASSERT_EQ(pid, preloaded_client_pid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectCreatedPIDByAppID) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ int pid = client_manager.find_client_pid_by_appid(arbitrary_client_appid);
+
+ ASSERT_EQ(pid, arbitrary_client_pid);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectExistingAppIDByPID) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ std::string appid = client_manager.find_client_appid_by_pid(preloaded_client_pid_1);
+
+ ASSERT_EQ(appid, preloaded_client_appid_1);
+}
+
+TEST_F(StorageWithOneClient, ReturnsCorrectCreatedPIDAppIDByPID) {
+ const std::string arbitrary_client_appid{"Client2"};
+ const int arbitrary_client_pid{2};
+
+ client_manager.create_client(arbitrary_client_pid, arbitrary_client_appid);
+
+ std::string appid = client_manager.find_client_appid_by_pid(arbitrary_client_pid);
+
+ ASSERT_EQ(appid, arbitrary_client_appid);
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}
--- /dev/null
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+
+SET(TEST_SOURCES
+ test_config.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_config.cpp
+)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ capi-appfw-application
+ capi-appfw-preference
+ multi-assistant
+ dlog
+ libxml-2.0
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FIND_PACKAGE(GTest REQUIRED)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
+
+SET(TEST_CONFIG test-config)
+ADD_EXECUTABLE(${TEST_CONFIG}
+ ${TEST_SOURCES}
+ )
+
+TARGET_LINK_LIBRARIES(${TEST_CONFIG} -ldl ${GTEST_LIBRARIES} pthread
+ ${EXTRA_LDFLAGS} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${TEST_CONFIG} DESTINATION bin)
+
+ADD_TEST(NAME ${TEST_CONFIG} COMMAND ${TEST_CONFIG})
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "service_config.h"
+
+#include <string>
+
+class StorageWithEmptyWakeWord : public testing::Test {
+public:
+ StorageWithEmptyWakeWord() {
+ }
+ virtual ~StorageWithEmptyWakeWord() {
+ }
+ void SetUp() override {
+ memset(wakeup_word_storage, 0x0, sizeof(wakeup_word_storage));
+ memset(wakeup_language_storage, 0x0, sizeof(wakeup_language_storage));
+ }
+ void TearDown() override {
+ }
+ CServiceConfig config;
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN];
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
+};
+
+class StorageWithAnArbitraryWakeWord : public testing::Test {
+public:
+ StorageWithAnArbitraryWakeWord() {
+ }
+ virtual ~StorageWithAnArbitraryWakeWord() {
+ }
+ void SetUp() override {
+ memset(wakeup_word_storage, 0x0, sizeof(wakeup_word_storage));
+ memset(wakeup_language_storage, 0x0, sizeof(wakeup_language_storage));
+
+ config.add_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+ }
+ void TearDown() override {
+ }
+ const std::string preloaded_wake_word{"Hi Preloaded"};
+ const std::string preloaded_language{"pr_LD"};
+ CServiceConfig config;
+ char wakeup_word_storage[MAX_WAKEUP_WORDS_NUM][MAX_WAKEUP_WORD_LEN];
+ char wakeup_language_storage[MAX_WAKEUP_WORDS_NUM][MAX_SUPPORTED_LANGUAGE_LEN];
+};
+
+TEST_F(StorageWithEmptyWakeWord, HasOneWakeWordAfterAdd) {
+ const std::string arbitrary_wake_word{"Hi Tizen"};
+ const std::string arbitrary_language{"ar_LA"};
+
+ config.add_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ int wake_word_num = config.get_custom_wake_word_num(
+ wakeup_word_storage, wakeup_language_storage);
+ ASSERT_EQ(wake_word_num, 1);
+}
+
+TEST_F(StorageWithEmptyWakeWord, HasTwoWakeWordsWhenDifferentLanguageAdded) {
+ const std::string arbitrary_wake_word{"Hi Tizen"};
+ const std::string arbitrary_language1{"ar_LA1"};
+ const std::string arbitrary_language2{"ar_LA2"};
+ config.add_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language1.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ config.add_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language2.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ int wake_word_num = config.get_custom_wake_word_num(
+ wakeup_word_storage, wakeup_language_storage);
+ ASSERT_EQ(wake_word_num, 2);
+}
+
+TEST_F(StorageWithEmptyWakeWord, RemovalFailsWhenNoMatchingEntryExists) {
+ const std::string arbitrary_wake_word{"Hi Tizen"};
+ const std::string arbitrary_language{"ar_LA"};
+
+ int ret = config.remove_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ ASSERT_EQ(ret, -1);
+}
+
+TEST_F(StorageWithAnArbitraryWakeWord, StillHasOneWakeWordAfterDuplicatedAdd) {
+ config.add_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ int wake_word_num = config.get_custom_wake_word_num(
+ wakeup_word_storage, wakeup_language_storage);
+ ASSERT_EQ(wake_word_num, 1);
+}
+
+TEST_F(StorageWithAnArbitraryWakeWord, HasZeroWakeWordAfterRemoval) {
+ config.remove_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ int wake_word_num = config.get_custom_wake_word_num(
+ wakeup_word_storage, wakeup_language_storage);
+ ASSERT_EQ(wake_word_num, 0);
+}
+
+TEST_F(StorageWithAnArbitraryWakeWord, RemovesItemRequestedForRemoval) {
+ const std::string arbitrary_wake_word{"Hi Tizen"};
+ const std::string arbitrary_language{"ar_LA"};
+ config.add_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+ config.remove_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ bool exists = config.has_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+ ASSERT_EQ(exists, false);
+}
+
+TEST_F(StorageWithAnArbitraryWakeWord, PreservesItemNotRequestedForRemoval) {
+ const std::string arbitrary_wake_word{"Hi Tizen"};
+ const std::string arbitrary_language{"ar_LA"};
+ config.add_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+ config.remove_custom_wake_word(
+ preloaded_wake_word.c_str(), preloaded_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+
+ bool exists = config.has_custom_wake_word(
+ arbitrary_wake_word.c_str(), arbitrary_language.c_str(),
+ wakeup_word_storage,
+ wakeup_language_storage);
+ ASSERT_EQ(exists, true);
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}
--- /dev/null
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/inc/
+ )
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+
+SET(TEST_SOURCES
+ test_service_main.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_main.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_ipc_dbus.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_ipc_dbus_dispatcher.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_plugin.cpp
+ ${CMAKE_SOURCE_DIR}/src/service_config.cpp
+ ${CMAKE_SOURCE_DIR}/src/client_manager.cpp
+)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ capi-appfw-application
+ capi-appfw-preference
+ capi-appfw-package-manager
+ capi-appfw-service-application
+ capi-message-port
+ multi-assistant
+ dlog
+ libxml-2.0
+ ecore
+ pkgmgr-info
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FIND_PACKAGE(GTest REQUIRED)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
+
+SET(TEST_SERVICE_MAIN test-service-main)
+ADD_EXECUTABLE(${TEST_SERVICE_MAIN}
+ ${TEST_SOURCES}
+ )
+
+TARGET_LINK_LIBRARIES(${TEST_SERVICE_MAIN} -ldl ${GTEST_LIBRARIES} pthread
+ ${EXTRA_LDFLAGS} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${TEST_SERVICE_MAIN} DESTINATION bin)
+
+ADD_TEST(NAME ${TEST_SERVICE_MAIN} COMMAND ${TEST_SERVICE_MAIN})
--- /dev/null
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "service_main.h"
+
+#include <string>
+#include <unistd.h>
+#include <stdlib.h>
+
+class CDummyApplicationManager : public IApplicationManager
+{
+public:
+ CDummyApplicationManager() {};
+ ~CDummyApplicationManager() {};
+
+ bool is_application_running(int pid) override { return false; }
+ bool is_application_running(const std::string& appid) override { return false; }
+ bool bring_app_to_foreground(const std::string& appid) override
+ {
+ brought_to_foreground_appid = appid;
+ return true;
+ }
+ bool launch_app_async(const std::string& appid, bool background) override
+ {
+ launched_appid = appid;
+ launched_option_background = background;
+ return true;
+ }
+ boost::optional<std::string> get_appid_by_pid(int pid) override { return boost::optional<std::string>{}; }
+public:
+ boost::optional<std::string> launched_appid;
+ boost::optional<bool> launched_option_background;
+ boost::optional<std::string> brought_to_foreground_appid;;
+};
+
+class CDummyPreferenceManager : public IPreferenceManager
+{
+public:
+ CDummyPreferenceManager() {}
+ ~CDummyPreferenceManager() {}
+
+ boost::optional<std::string> get_string(const std::string& key) override
+ {
+ boost::optional<std::string> ret;
+ const auto& iter = key_value_string.find(key);
+ if (iter != key_value_string.end()) {
+ ret = iter->second;
+ }
+ return ret;
+ }
+ boost::optional<int> get_int(const std::string& key) override
+ {
+ boost::optional<int> ret;
+ const auto& iter = key_value_int.find(key);
+ if (iter != key_value_int.end()) {
+ ret = iter->second;
+ }
+ return ret;
+ }
+ boost::optional<bool> get_bool(const std::string& key) override
+ {
+ boost::optional<bool> ret;
+ const auto& iter = key_value_bool.find(key);
+ if (iter != key_value_bool.end()) {
+ ret = iter->second;
+ }
+ return ret;
+ }
+
+ bool register_changed_callback(
+ const std::string& key, preference_changed_cb calback, void* user_data) override { return true; }
+ bool unregister_changed_callback(
+ const std::string& key, preference_changed_cb callback) override { return true; }
+public:
+ std::map<std::string, std::string> key_value_string;
+ std::map<std::string, int> key_value_int;
+ std::map<std::string, bool> key_value_bool;
+};
+
+class DefaultFixure : public testing::Test
+{
+public:
+ DefaultFixure() {
+ }
+ virtual ~DefaultFixure() {
+ }
+ void SetUp() override {
+ }
+ void TearDown() override {
+ }
+ CDummyApplicationManager application_manager;
+ CDummyPreferenceManager preference_manager;
+
+ CServiceMain service{application_manager, preference_manager};
+};
+
+TEST_F(DefaultFixure, BringsDefaultAssistantToFrontOnAssistantActivatedPreprocessingStateEvent) {
+ std::string assistant_appid{"Arbitrary Assistant"};
+ ma_assistant_info_s info;
+ info.app_id = assistant_appid.c_str();
+ service.add_assistant_info(&info);
+ service.mas_process_preprocessing_state_event(PREPROCESSING_STATE_EVENT_ASSISTANT_ACTIVATED);
+
+ bool brought = false;
+ if (application_manager.brought_to_foreground_appid) {
+ brought = true;
+ }
+
+ ASSERT_TRUE(brought);
+}
+
+int main(int argc, char** argv) {
+ const char* seconds = getenv("TEST_SLEEP_SECONDS");
+ if (seconds) {
+ sleep(atoi(seconds));
+ }
+ testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}