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_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"
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"
typedef int (*wakeup_manager_set_assistant_wakeup_engine)(const char* appid, const char* engine);
+#define MA_WAKEUP_MANAGER_FUNC_SET_DEFAULT_ASSISTANT "wakeup_manager_set_default_assistant"
+typedef int (*wakeup_manager_set_default_assistant)(const char* appid);
+#define MA_WAKEUP_MANAGER_FUNC_GET_DEFAULT_ASSISTANT "wakeup_manager_get_default_assistant"
+typedef int (*wakeup_manager_get_default_assistant)(const char** appid);
#define MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE "wakeup_manager_set_language"
typedef int (*wakeup_manager_set_language)(const char* language);
#define MA_WAKEUP_MANAGER_FUNC_ACTIVATE "wakeup_manager_activate"
wakeup_manager_add_assistant_wakeup_word add_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;
+ wakeup_manager_get_default_assistant get_default_assistant;
wakeup_manager_set_language set_language;
wakeup_manager_activate activate;
wakeup_manager_deactivate deactivate;
bool set_language(string language);
void set_assistant_activated(string appid, bool activated);
+ bool get_assistant_activated(string appid);
void set_wake_word_audio_require_flag(bool require);
void start_streaming_current_utterance_data();
bool add_assistant_wakeup_word(string appid, string wakeup_word, string language);
bool set_assistant_wakeup_engine(string appid, string engine);
+ bool set_assistant_enabled(string appid, bool enabled);
+ bool get_assistant_enabled(string appid);
+ bool set_default_assistant(string appid);
+ string get_default_assistant();
+
bool update_voice_feedback_state(string appid, bool state);
bool send_assistant_specific_command(string appid, string command);
bool set_background_volume(string appid, double ratio);
{
public:
bool on_voice_input_language_changed(const char* language) override;
+ bool on_assistant_enabled_info_changed(const char* appid, bool enabled) override;
+ bool on_default_assistant_appid_changed(const char* appid) override;
void set_wakeup_manager(CWakeupManager *manager) { mWakeupManager = manager; }
private:
vector<string> languageList;
} AssistantLanguageInfo;
vector<AssistantLanguageInfo> mAssistantLanguageInfo;
- map<string, bool> mAssistantActivated;
+ map<string, bool> mAssistantSupportsCurrentLanguage;
+ map<string, bool> mAssistantEnabled;
vector<IWakeupEventObserver*> mObservers;
bool mVoiceKeyPressed{false};
string mCurrentLanguage;
+ string mCurrentDefaultAssistant;
STREAMING_MODE mStreamingMode{STREAMING_MODE::NONE};
Ecore_Timer* mStreamingDurationTimer{nullptr};
} // wakeup
} // multiassistant
-#endif /* _WAKEUP_MANAGER_H_ */
+#endif /* _WAKEUP_MANAGER_H_ */
\ No newline at end of file
EXPORT_API int wakeup_manager_set_assistant_wakeup_engine(const char* appid, const char *engine);
+EXPORT_API int wakeup_manager_set_default_assistant(const char* appid);
+
+EXPORT_API int wakeup_manager_get_default_assistant(const char** appid);
+
EXPORT_API int wakeup_manager_set_language(const char* language);
EXPORT_API int wakeup_manager_activate(void);
using namespace std;
-#define DEFAULT_ASSISTANT_APPID "org.tizen.voice-app"
-
#define WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID "db/multi-assistant/default_assistant_appid"
#define WAKEUP_SETTINGS_KEY_UI_PANEL_ENABLED "db/multi-assistant/ui_panel_enabled"
#define WAKEUP_SETTINGS_KEY_CONVERSATION_TIMEOUT "db/multi-assistant/conversation_timeout"
public:
virtual ~ISettingsEventObserver() = default;
virtual bool on_voice_input_language_changed(const char* language) = 0;
+ virtual bool on_assistant_enabled_info_changed(const char* appid, bool enabled) = 0;
+ virtual bool on_default_assistant_appid_changed(const char* appid) = 0;
};
class CWakeupSettings
private:
vector<ISettingsEventObserver*> mObservers;
- string mDefaultAssistantAppid{DEFAULT_ASSISTANT_APPID};
+ string mDefaultAssistantAppid;
bool mUiPanelEnabled{true};
float mConversationTimeout{5.0};
bool mMultipleMode{true};
- vector<string> mEnabledAssistants{DEFAULT_ASSISTANT_APPID};
+ vector<string> mEnabledAssistants;
float mWakeupPolicyDelay{0.1};
vector<string> mWakeupPolicyPriority; // No priority by default
float mStreamingDurationMax{10.0};
+ string mVoiceInputLanguage;
};
} // wakeup
void CWakeupEngineManager::engine_feed_audio_data(long time, void* data, int len)
{
for (const auto& info : mEngineInfo) {
- if (info.audio_data_require_status &&
+ if (info.activated &&
+ info.audio_data_require_status &&
info.interface.feed_audio_data) {
int ret = info.interface.feed_audio_data(time, data, len);
if (0 != ret) {
mAudioEventObserver.set_wakeup_manager(this);
mSettingsEventObserver.set_wakeup_manager(this);
+ mWakeupSettings.subscribe(&mSettingsEventObserver);
mWakeupSettings.initialize();
mAudioEventObserver.set_wakeup_engine_manager(&mWakeupEngineManager);
dependency_resolver_initialize(interface);
- mWakeupSettings.subscribe(&mSettingsEventObserver);
-
MWR_LOGD("[END]");
return true;
}
info.languageList.push_back(language);
mAssistantLanguageInfo.push_back(info);
}
+ if (0 == mCurrentLanguage.compare(language)) {
+ mAssistantSupportsCurrentLanguage[appid] = true;
+ if (true == mAssistantEnabled[appid]) {
+ mWakeupEngineManager.set_assistant_activated(appid, true);
+ }
+ }
MWR_LOGD("[END]");
return true;
}
return true;
}
+bool CWakeupManager::set_assistant_enabled(string appid, bool enabled)
+{
+ MWR_LOGD("[ENTER]");
+
+ mAssistantEnabled[appid] = enabled;
+ bool activated = enabled;
+ if (false == mAssistantSupportsCurrentLanguage[appid]) {
+ activated = false;
+ }
+ if (0 == appid.compare(mCurrentDefaultAssistant)) {
+ activated = true;
+ }
+ mWakeupEngineManager.set_assistant_activated(appid, activated);
+
+ MWR_LOGD("[END]");
+ return true;
+}
+
+bool CWakeupManager::set_default_assistant(string appid)
+{
+ MWR_LOGD("[ENTER]");
+
+ /* Check if previous default assistant has to be deactivated */
+ bool activated = true;
+ if (false == mAssistantSupportsCurrentLanguage[mCurrentDefaultAssistant]) {
+ activated = false;
+ }
+ if (false == mAssistantEnabled[mCurrentDefaultAssistant]) {
+ activated = false;
+ }
+ mWakeupEngineManager.set_assistant_activated(mCurrentDefaultAssistant, activated);
+
+ /* New default assistant has to be activated no matter what */
+ mWakeupEngineManager.set_assistant_activated(appid, true);
+ mCurrentDefaultAssistant = appid;
+
+ MWR_LOGD("[END]");
+ return true;
+}
+
+string CWakeupManager::get_default_assistant()
+{
+ return mCurrentDefaultAssistant;
+}
+
+bool CWakeupManager::get_assistant_enabled(string appid)
+{
+ return mAssistantEnabled[appid];
+}
+
bool CWakeupManager::set_language(string language)
{
bool ret = false;
}
}
if(false == found) {
- mAssistantActivated[info.appid] = false;
+ mAssistantSupportsCurrentLanguage[info.appid] = false;
} else {
- mAssistantActivated[info.appid] = true;
+ mAssistantSupportsCurrentLanguage[info.appid] = true;
}
- mWakeupEngineManager.set_assistant_activated(info.appid, found);
+ bool activated = found;
+ if (false == mAssistantEnabled[info.appid]) {
+ activated = false;
+ }
+ if (0 == info.appid.compare(mCurrentDefaultAssistant)) {
+ activated = true;
+ }
+ mWakeupEngineManager.set_assistant_activated(info.appid, activated);
}
mWakeupEngineManager.set_language(language);
{
MWR_LOGD("[ENTER]");
if (nullptr == mWakeupManager) return false;
+ if (nullptr == wakeup_info.wakeup_appid) return false;
+
+ if (0 != mWakeupManager->get_default_assistant().compare(wakeup_info.wakeup_appid)) {
+ if (false == mWakeupManager->get_assistant_enabled(string{wakeup_info.wakeup_appid})) {
+ MWR_LOGE("Wakeup event with deactivated appid : %s", wakeup_info.wakeup_appid);
+ return false;
+ }
+ }
CWakeupPolicy* policy = mWakeupManager->get_wakeup_policy();
if (policy) {
return true;
}
+bool CWakeupManager::CSettingsEventObserver::on_assistant_enabled_info_changed(
+ const char* appid, bool enabled)
+{
+ if (nullptr == mWakeupManager || nullptr == appid) return false;
+ mWakeupManager->set_assistant_enabled(std::string(appid), enabled);
+ return true;
+}
+
+bool CWakeupManager::CSettingsEventObserver::on_default_assistant_appid_changed(
+ const char* appid)
+{
+ if (nullptr == mWakeupManager || nullptr == appid) return false;
+ mWakeupManager->set_default_assistant(std::string(appid));
+ return true;
+}
+
} // wakeup
} // multiassistant
return 0;
}
+int wakeup_manager_set_default_assistant(const char* appid)
+{
+ MWR_LOGD("[ENTER]");
+
+ if (NULL == appid) {
+ MWR_LOGD("[ERROR] Parameter is invalid, appid(%s)", appid);
+ return -1;
+ }
+
+ MWR_LOGD("[DEBUG] default_assistant appid(%s)", appid);
+ g_wakeup_manager.set_default_assistant(string{appid});
+
+ MWR_LOGD("[END]");
+ return 0;
+}
+
+int wakeup_manager_get_default_assistant(const char** appid)
+{
+ static string default_assistant;
+ default_assistant = g_wakeup_manager.get_default_assistant();
+
+ if (default_assistant.empty()) {
+ *appid = nullptr;
+ } else {
+ *appid = default_assistant.c_str();
+ }
+ return 0;
+}
+
int wakeup_manager_set_language(const char* language)
{
MWR_LOGD("[ENTER]");
namespace wakeup
{
+/* Utility function for checking if an element exists in a container */
+template<class C, class T>
+static auto contains(const C& v, const T& x) -> decltype(end(v), true)
+{
+ return end(v) != find(begin(v), end(v), x);
+}
+
CWakeupSettings::CWakeupSettings()
{
}
{
}
-static void wakeup_setting_input_language_changed_cb(keynode_t *node, void* data)
+static void wakeup_setting_input_language_changed_cb(keynode_t* node, void* data)
{
+ MWR_LOGD("[ENTER]");
if (nullptr == node) return;
CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
}
}
+static void wakeup_setting_enabled_assistants_changed_cb(keynode_t* node, void* data)
+{
+ MWR_LOGD("[ENTER]");
+ if (nullptr == node) return;
+
+ CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
+ if (nullptr == settings) return;
+
+ if (VCONF_TYPE_STRING == node->type) {
+ vector<string> newlyAddedAssistants;
+ vector<string> newlyRemovedAssistants;
+ const char* value = static_cast<const char*>(node->value.s);
+ if (value) {
+ vector<string> previouslyEnabledAssistants = settings->get_enabled_assistants();
+ vector<string> currentlyEnabledAssistants;
+ string token;
+ istringstream iss(value);
+ currentlyEnabledAssistants.clear();
+ while (getline(iss, token, ';')) {
+ currentlyEnabledAssistants.push_back(token);
+ MWR_LOGD("enabled_assistants : %s", token.c_str());
+ }
+
+ for (const auto& assistant : currentlyEnabledAssistants) {
+ if (!contains(previouslyEnabledAssistants, assistant)) {
+ newlyAddedAssistants.push_back(assistant);
+ }
+ }
+ for (const auto& assistant : previouslyEnabledAssistants) {
+ if (!contains(currentlyEnabledAssistants, assistant)) {
+ newlyRemovedAssistants.push_back(assistant);
+ }
+ }
+ }
+
+ vector<ISettingsEventObserver*> observers = settings->get_observers();
+ for (const auto& observer : observers) {
+ if (observer) {
+ for (const auto& assistant : newlyAddedAssistants) {
+ if (!observer->on_assistant_enabled_info_changed(assistant.c_str(), true)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ for (const auto& assistant : newlyRemovedAssistants) {
+ if (!observer->on_assistant_enabled_info_changed(assistant.c_str(), false)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ }
+ }
+ } else {
+ LOGE("[Settings ERROR] the value type is not string : %d", node->type);
+ }
+}
+
+static void wakeup_setting_default_assistant_appid_changed_cb(keynode_t* node, void* data)
+{
+ MWR_LOGD("[ENTER]");
+ if (nullptr == node) return;
+
+ CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
+ if (nullptr == settings) return;
+
+ if (VCONF_TYPE_STRING == node->type) {
+ const char* value = static_cast<const char*>(node->value.s);
+ vector<ISettingsEventObserver*> observers = settings->get_observers();
+ for (const auto& observer : observers) {
+ if (observer) {
+ if (!observer->on_default_assistant_appid_changed(value)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ }
+ } else {
+ LOGE("[Settings ERROR] the value type is not string : %d", node->type);
+ }
+}
+
void CWakeupSettings::initialize()
{
int vconf_ret;
if (vconf_str) {
mDefaultAssistantAppid = vconf_str;
MWR_LOGD("default_assistant_appid : %s", mDefaultAssistantAppid.c_str());
+ for (const auto& observer : mObservers) {
+ if (observer) {
+ if (!observer->on_default_assistant_appid_changed(vconf_str)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ }
free(vconf_str);
vconf_str = nullptr;
}
while (getline(iss, token, ';')) {
mEnabledAssistants.push_back(token);
MWR_LOGD("enabled_assistants : %s", token.c_str());
+ for (const auto& observer : mObservers) {
+ if (observer) {
+ if (!observer->on_assistant_enabled_info_changed(token.c_str(), true)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ }
}
free(vconf_str);
vconf_str = nullptr;
mStreamingDurationMax = vconf_double;
MWR_LOGD("streaming_duration_max : %f", mStreamingDurationMax);
}
+ vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE);
+ if (vconf_str) {
+ mVoiceInputLanguage = vconf_str;
+ MWR_LOGD("voice input language : %s", mVoiceInputLanguage.c_str());
+ for (const auto& observer : mObservers) {
+ if (observer) {
+ if (!observer->on_voice_input_language_changed(vconf_str)) {
+ LOGW("[Settings WARNING] One of the observer returned false");
+ }
+ }
+ }
+ free(vconf_str);
+ vconf_str = nullptr;
+ }
vconf_notify_key_changed(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE,
wakeup_setting_input_language_changed_cb, this);
+ vconf_notify_key_changed(WAKEUP_SETTINGS_KEY_ENABLED_ASSISTANTS,
+ wakeup_setting_enabled_assistants_changed_cb, this);
+ vconf_notify_key_changed(WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID,
+ wakeup_setting_default_assistant_appid_changed_cb, this);
}
void CWakeupSettings::deinitialize()
{
vconf_ignore_key_changed(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE, NULL);
+ vconf_ignore_key_changed(WAKEUP_SETTINGS_KEY_ENABLED_ASSISTANTS, NULL);
+ vconf_ignore_key_changed(WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID, NULL);
}
void CWakeupSettings::subscribe(ISettingsEventObserver *observer)
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_DEFAULT_ASSISTANT_APPID "db/multi-assistant/default_assistant_appid"
#define WAKEUP_SETTINGS_KEY_PREPROCESSING_ASSISTANT_APPID "db/multi-assistant/preprocessing_assistant_appid"
#define WAKEUP_SETTINGS_KEY_PRELAUNCH_MODE "db/multi-assistant/prelaunch_mode"
/* 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();
- vconf_set_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED, 1);
- vconf_notify_key_changed(MULTI_ASSISTANT_SETTINGS_ACTIVATED, mas_active_state_changed_cb, NULL);
+ 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
}
/* 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) {
- char *vconf_str;
- vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID);
- if (vconf_str) {
- MAS_LOGD("prelaunching default_assistant_appid : %s", vconf_str);
- mas_launch_client_by_appid(vconf_str, CLIENT_LAUNCH_MODE_PRELAUNCH);
- free(vconf_str);
- vconf_str = NULL;
+ const char *default_assistant = NULL;
+ if (0 == multi_assistant_service_plugin_get_default_assistant(&default_assistant)) {
+ MAS_LOGD("prelaunching default_assistant_appid : %s", default_assistant);
+ mas_launch_client_by_appid(default_assistant, CLIENT_LAUNCH_MODE_PRELAUNCH);
}
}
_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);
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;