Modified not to load wakeup engine with wake_word_detection turned off
[platform/core/uifw/multi-assistant-service.git] / plugins / wakeup-manager / src / wakeup_settings.cpp
1 #include "wakeup_settings.h"
2 #include "wakeup_manager_main.h"
3
4 #include <sstream>
5 #include <algorithm>
6 #include <json/json.h>
7
8 namespace multiassistant
9 {
10 namespace wakeup
11 {
12
13 /* Utility function for checking if an element exists in a container */
14 template<class C, class T>
15 static auto contains(const C& v, const T& x) -> decltype(end(v), true)
16 {
17         return end(v) != find(begin(v), end(v), x);
18 }
19
20 CWakeupSettings::CWakeupSettings()
21 {
22 }
23
24 CWakeupSettings::~CWakeupSettings()
25 {
26 }
27
28 static void wakeup_setting_input_language_changed_cb(keynode_t* node, void* data)
29 {
30         MWR_LOGD("[ENTER]");
31         if (nullptr == node) return;
32
33         CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
34         if (nullptr == settings) return;
35
36         if (VCONF_TYPE_STRING == node->type) {
37                 const char* value = static_cast<const char*>(node->value.s);
38                 const auto& observers = settings->get_observers();
39                 for (const auto& observer : observers) {
40                         if (observer) {
41                                 if (!observer->on_voice_input_language_changed(value)) {
42                                         LOGW("[Settings WARNING] One of the observer returned false");
43                                 }
44                         }
45                 }
46         } else {
47                 LOGE("[Settings ERROR] the value type is not string : %d", node->type);
48         }
49 }
50
51 static void wakeup_setting_enabled_assistants_changed_cb(keynode_t* node, void* data)
52 {
53         MWR_LOGD("[ENTER]");
54         if (nullptr == node) return;
55
56         CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
57         if (nullptr == settings) return;
58
59         if (VCONF_TYPE_STRING == node->type) {
60                 vector<string> newlyAddedAssistants;
61                 vector<string> newlyRemovedAssistants;
62                 const char* value = static_cast<const char*>(node->value.s);
63                 if (value) {
64                         vector<string> previouslyEnabledAssistants = settings->get_enabled_assistants();
65                         vector<string> currentlyEnabledAssistants;
66                         string token;
67                         istringstream iss(value);
68                         currentlyEnabledAssistants.clear();
69                         while (getline(iss, token, ';')) {
70                                 currentlyEnabledAssistants.push_back(token);
71                                 MWR_LOGD("enabled_assistants : %s", token.c_str());
72                         }
73
74                         for (const auto& assistant : currentlyEnabledAssistants) {
75                                 if (!contains(previouslyEnabledAssistants, assistant)) {
76                                         newlyAddedAssistants.push_back(assistant);
77                                 }
78                         }
79                         for (const auto& assistant : previouslyEnabledAssistants) {
80                                 if (!contains(currentlyEnabledAssistants, assistant)) {
81                                         newlyRemovedAssistants.push_back(assistant);
82                                 }
83                         }
84                 }
85
86                 const auto& observers = settings->get_observers();
87                 for (const auto& observer : observers) {
88                         if (observer) {
89                                 for (const auto& assistant : newlyAddedAssistants) {
90                                         if (!observer->on_assistant_enabled_info_changed(assistant.c_str(), true)) {
91                                                 LOGW("[Settings WARNING] One of the observer returned false");
92                                         }
93                                 }
94                                 for (const auto& assistant : newlyRemovedAssistants) {
95                                         if (!observer->on_assistant_enabled_info_changed(assistant.c_str(), false)) {
96                                                 LOGW("[Settings WARNING] One of the observer returned false");
97                                         }
98                                 }
99                         }
100                 }
101         } else {
102                 LOGE("[Settings ERROR] the value type is not string : %d", node->type);
103         }
104 }
105
106 static void wakeup_setting_default_assistant_appid_changed_cb(keynode_t* node, void* data)
107 {
108         MWR_LOGD("[ENTER]");
109         if (nullptr == node) return;
110
111         CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
112         if (nullptr == settings) return;
113
114         if (VCONF_TYPE_STRING == node->type) {
115                 const char* value = static_cast<const char*>(node->value.s);
116                 const auto& observers = settings->get_observers();
117                 for (const auto& observer : observers) {
118                         if (observer) {
119                                 if (!observer->on_default_assistant_appid_changed(value)) {
120                                         LOGW("[Settings WARNING] One of the observer returned false");
121                                 }
122                         }
123                 }
124         } else {
125                 LOGE("[Settings ERROR] the value type is not string : %d", node->type);
126         }
127 }
128
129 static void wakeup_setting_multiple_mode_changed_cb(keynode_t* node, void* data)
130 {
131         MWR_LOGD("[ENTER]");
132
133         CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
134         if (nullptr == settings) return;
135
136         const auto& observers = settings->get_observers();
137         for (const auto& observer : observers) {
138                 if (observer) {
139                         if (!observer->on_multiple_mode_changed()) {
140                                 LOGW("[Settings WARNING] One of the observer returned false");
141                         }
142                 }
143         }
144 }
145
146 static void wakeup_setting_enabled_wake_word_detection_changed_cb(keynode_t* node, void* data)
147 {
148         MWR_LOGD("[ENTER]");
149
150         CWakeupSettings* settings = static_cast<CWakeupSettings*>(data);
151         if (nullptr == settings) return;
152
153         const auto& observers = settings->get_observers();
154         for (const auto& observer : observers) {
155                 if (observer) {
156                         if (!observer->on_wake_word_detection_enabled_info_changed()) {
157                                 LOGW("[Settings WARNING] One of the observer returned false");
158                         }
159                 }
160         }
161 }
162
163 void CWakeupSettings::initialize(map<string, string> custom_keys)
164 {
165         int vconf_ret;
166         char *vconf_str;
167         int vconf_bool;
168         double vconf_double;
169
170         mCustomVconfKeys.clear();
171         mCustomVconfKeys = custom_keys;
172
173         vconf_str = vconf_get_str(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID].c_str());
174         if (vconf_str) {
175                 mDefaultAssistantAppid = vconf_str;
176                 MWR_LOGD("default_assistant_appid : %s", mDefaultAssistantAppid.c_str());
177                 for (const auto& observer : mObservers) {
178                         if (observer) {
179                                 if (!observer->on_default_assistant_appid_changed(vconf_str)) {
180                                         LOGW("[Settings WARNING] One of the observer returned false");
181                                 }
182                         }
183                 }
184                 free(vconf_str);
185                 vconf_str = nullptr;
186         }
187         vconf_ret = vconf_get_bool(WAKEUP_SETTINGS_KEY_UI_PANEL_ENABLED, &vconf_bool);
188         if (0 == vconf_ret) {
189                 mUiPanelEnabled = vconf_bool;
190                 MWR_LOGD("ui_panel_enabled : %s", (mUiPanelEnabled ? "true" : "false"));
191         }
192         vconf_ret = vconf_get_dbl(WAKEUP_SETTINGS_KEY_CONVERSATION_TIMEOUT, &vconf_double);
193         if (0 == vconf_ret) {
194                 mConversationTimeout = vconf_double;
195                 MWR_LOGD("conversation_timeout : %f", mConversationTimeout);
196         }
197         vconf_ret = vconf_get_bool(WAKEUP_SETTINGS_KEY_MULTIPLE_MODE, &vconf_bool);
198         if (0 == vconf_ret) {
199                 mMultipleMode = vconf_bool;
200                 MWR_LOGD("multiple_mode : %s", (mMultipleMode ? "true" : "false"));
201         }
202         if (true == mMultipleMode) {
203                 vconf_str = vconf_get_str(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_ENABLED_ASSISTANTS].c_str());
204                 if (vconf_str) {
205                         string token;
206                         istringstream iss(vconf_str);
207                         mEnabledAssistants.clear();
208                         while (getline(iss, token, ';')) {
209                                 mEnabledAssistants.push_back(token);
210                                 MWR_LOGD("enabled_assistants : %s", token.c_str());
211                                 for (const auto& observer : mObservers) {
212                                         if (observer) {
213                                                 if (!observer->on_assistant_enabled_info_changed(token.c_str(), true)) {
214                                                         LOGW("[Settings WARNING] One of the observer returned false");
215                                                 }
216                                         }
217                                 }
218                         }
219                         free(vconf_str);
220                         vconf_str = nullptr;
221                 }
222         }
223         vconf_str = vconf_get_str(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_WAKE_WORD_DETECTION_ENABLED].c_str());
224         if (vconf_str) {
225                 Json::Reader reader;
226                 Json::Value root;
227                 mWakeWordDisabledAssistants.clear();
228                 if (!reader.parse(vconf_str, root)) {
229                         LOGW("[Settings WARNING] Failed to parse Json : %s", reader.getFormattedErrorMessages().c_str());
230                 } else {
231                         auto member = root.getMemberNames();
232                         for (string m : member) {
233                                 if (0 == root[m].asString().compare("off")) {
234                                         mWakeWordDisabledAssistants.push_back(m);
235                                         MWR_LOGD("wake_word_detection_disabled assistant : %s", m.c_str());
236                                 }
237                         }
238                 }
239                 free(vconf_str);
240                 vconf_str = nullptr;
241         }
242         vconf_ret = vconf_get_dbl(WAKEUP_SETTINGS_KEY_WAKEUP_POLICY_DELAY, &vconf_double);
243         if (0 == vconf_ret) {
244                 mWakeupPolicyDelay = vconf_double;
245                 MWR_LOGD("conversation_timeout : %f", mWakeupPolicyDelay);
246         }
247         vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_WAKEUP_POLICY_PRIORITY);
248         if (vconf_str) {
249                 string token;
250                 istringstream iss(vconf_str);
251                 mWakeupPolicyPriority.clear();
252                 while (getline(iss, token, ';')) {
253                         mWakeupPolicyPriority.push_back(token);
254                         MWR_LOGD("wakeup_policy_priority : %s", token.c_str());
255                 }
256                 free(vconf_str);
257                 vconf_str = nullptr;
258         }
259         vconf_ret = vconf_get_dbl(WAKEUP_SETTINGS_KEY_STREAMING_DURATION_MAX, &vconf_double);
260         if (0 == vconf_ret) {
261                 mStreamingDurationMax = vconf_double;
262                 MWR_LOGD("streaming_duration_max : %f", mStreamingDurationMax);
263         }
264         vconf_str = vconf_get_str(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE);
265         if (vconf_str) {
266                 mVoiceInputLanguage = vconf_str;
267                 MWR_LOGD("voice input language : %s", mVoiceInputLanguage.c_str());
268                 for (const auto& observer : mObservers) {
269                         if (observer) {
270                                 if (!observer->on_voice_input_language_changed(vconf_str)) {
271                                         LOGW("[Settings WARNING] One of the observer returned false");
272                                 }
273                         }
274                 }
275                 free(vconf_str);
276                 vconf_str = nullptr;
277         }
278
279         vconf_notify_key_changed(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE,
280                 wakeup_setting_input_language_changed_cb, this);
281         vconf_notify_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID].c_str(),
282                 wakeup_setting_default_assistant_appid_changed_cb, this);
283         if (true == mMultipleMode) {
284                 vconf_notify_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_ENABLED_ASSISTANTS].c_str(),
285                         wakeup_setting_enabled_assistants_changed_cb, this);
286         }
287         vconf_notify_key_changed(WAKEUP_SETTINGS_KEY_MULTIPLE_MODE,
288                 wakeup_setting_multiple_mode_changed_cb, this);
289         vconf_notify_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_WAKE_WORD_DETECTION_ENABLED].c_str(),
290                 wakeup_setting_enabled_wake_word_detection_changed_cb, this);
291 }
292
293 void CWakeupSettings::deinitialize()
294 {
295         vconf_ignore_key_changed(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE,
296                 wakeup_setting_input_language_changed_cb);
297         vconf_ignore_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID].c_str(),
298                 wakeup_setting_default_assistant_appid_changed_cb);
299         if (true == mMultipleMode) {
300                 vconf_ignore_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_ENABLED_ASSISTANTS].c_str(),
301                         wakeup_setting_enabled_assistants_changed_cb);
302         }
303         vconf_ignore_key_changed(WAKEUP_SETTINGS_KEY_MULTIPLE_MODE,
304                 wakeup_setting_multiple_mode_changed_cb);
305         vconf_ignore_key_changed(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_WAKE_WORD_DETECTION_ENABLED].c_str(),
306                 wakeup_setting_enabled_wake_word_detection_changed_cb);
307 }
308
309 void CWakeupSettings::subscribe(ISettingsEventObserver *observer)
310 {
311         mObservers.push_back(observer);
312 }
313
314 void CWakeupSettings::unsubscribe(ISettingsEventObserver *observer)
315 {
316         auto iter = find(mObservers.begin(), mObservers.end(), observer);
317         if (iter != mObservers.end()) {
318                 mObservers.erase(iter);
319         }
320 }
321
322 const vector<ISettingsEventObserver*>& CWakeupSettings::get_observers()
323 {
324         return mObservers;
325 }
326
327 string CWakeupSettings::get_default_assistant_appid()
328 {
329         char *vconf_str;
330         vconf_str = vconf_get_str(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID].c_str());
331         MWR_LOGD("vconf default_assistant_appid : %s", vconf_str);
332         if (vconf_str) {
333                 mDefaultAssistantAppid = vconf_str;
334                 MWR_LOGD("member default_assistant_appid : %s", mDefaultAssistantAppid.c_str());
335                 free(vconf_str);
336                 vconf_str = nullptr;
337         }
338
339         return mDefaultAssistantAppid;
340 }
341
342 void CWakeupSettings::set_default_assistant_appid(std::string appid)
343 {
344         if (appid.compare(get_default_assistant_appid()) == 0) {
345                 MWR_LOGE("Default assistant appid not changed, ignoring...");
346                 return;
347         }
348         int ret = vconf_set_str(mCustomVconfKeys[WAKEUP_SETTINGS_KEY_DEFAULT_ASSISTANT_APPID].c_str(), appid.c_str());
349         MWR_LOGD("default_assistant_appid : %s, %d", appid.c_str(), ret);
350         mDefaultAssistantAppid = appid;
351 }
352
353 bool CWakeupSettings::get_ui_panel_enabled()
354 {
355         return mUiPanelEnabled;
356 }
357
358 float CWakeupSettings::get_conversation_timeout()
359 {
360         return mConversationTimeout;
361 }
362
363 bool CWakeupSettings::get_multiple_mode()
364 {
365         return mMultipleMode;
366 }
367
368 vector<string> CWakeupSettings::get_enabled_assistants()
369 {
370         return mEnabledAssistants;
371 }
372
373 float CWakeupSettings::get_wakeup_policy_delay()
374 {
375         return mWakeupPolicyDelay;
376 }
377
378 vector<string> CWakeupSettings::get_wakeup_policy_priority()
379 {
380         return mWakeupPolicyPriority;
381 }
382
383 float CWakeupSettings::get_streaming_duration_max()
384 {
385         return mStreamingDurationMax;
386 }
387
388 std::string CWakeupSettings::get_current_language(void)
389 {
390         std::string result{"en_US"};
391         char* language = vconf_get_str(WAKEUP_SETTINGS_KEY_VOICE_INPUT_LANGUAGE);
392         if (language) {
393                 result = language;
394                 free(language);
395         }
396         return result;
397 }
398
399 vector<string> CWakeupSettings::get_wake_word_disabled_assistants()
400 {
401         return mWakeWordDisabledAssistants;
402 }
403
404 } // wakeup
405 } // multiassistant