59934bd6ea843e273367cdcdd5df95edde23cb0e
[platform/core/uifw/multi-assistant-service.git] / plugins / wakeup-manager / src / wakeup_manager.cpp
1 /*
2  * Copyright 2018-2019 Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "wakeup_manager.h"
18 #include "wakeup_manager_main.h"
19 #include "wakeup_policy_default.h"
20 #include "wakeup_policy_external.h"
21 #include "dependency_resolver.h"
22
23 #include <algorithm>
24 #include <iostream>
25
26 #include <boost/optional.hpp>
27
28 namespace multiassistant
29 {
30 namespace wakeup
31 {
32
33 static bool check_language_valid(string language)
34 {
35         bool valid = true;
36         if (0 == language.length()) {
37                 valid = false;
38         }
39         return valid;
40 }
41
42 static bool initialize_wakeup_event_info(mas_wakeup_event_info* wakeup_info)
43 {
44         bool ret = false;
45         if (wakeup_info) {
46                 ret = true;
47
48                 wakeup_info->wakeup_appid = nullptr;
49                 wakeup_info->wakeup_word = nullptr;
50                 wakeup_info->wakeup_language = nullptr;
51                 wakeup_info->wakeup_voice_id = nullptr;
52                 wakeup_info->wakeup_engine = nullptr;
53                 wakeup_info->wakeup_confidence_score = 0.0f;
54
55                 wakeup_info->wakeup_start_time = 0;
56                 wakeup_info->wakeup_end_time = 0L;
57                 wakeup_info->wakeup_time_valid = false;
58
59                 wakeup_info->extra_data = nullptr;
60                 wakeup_info->extra_data_length = 0;
61                 wakeup_info->extra_data_description = nullptr;
62         }
63         return ret;
64 }
65
66 CWakeupManager::CWakeupManager(IWakeupEventObserver* wakeup_observer, ISettingValueObserver* setting_observer)
67 {
68         initialize_wakeup_event_info(&mLastWakeupEventInfo);
69
70         if (wakeup_observer) {
71                 subscribe_wakeup_observer(wakeup_observer);
72         }
73         if (setting_observer) {
74                 subscribe_setting_observer(setting_observer);
75         }
76 }
77
78 CWakeupManager::~CWakeupManager()
79 {
80         MWR_LOGI("Wakeup Manager is now being destroyed");
81 }
82
83 void CWakeupManager::initialize_wakeup_policy()
84 {
85         mWakeupPolicy.reset(new CWakeupPolicyExternal{&mPolicyEventObserver});
86         if (nullptr == mWakeupPolicy || !(mWakeupPolicy->valid())) {
87                 mWakeupPolicy.reset(new CWakeupPolicyDefault{&mPolicyEventObserver});
88
89                 /* Default Policy specific initialization */
90                 CWakeupPolicyDefault *policy =
91                         dynamic_cast<CWakeupPolicyDefault*>(mWakeupPolicy.get());
92                 if (policy) {
93                         int priority = 0;
94
95                         policy->set_delay(mWakeupSettings.get_wakeup_policy_delay());
96                         MWR_LOGD("Setting Delay : %f", mWakeupSettings.get_wakeup_policy_delay());
97                         for (const auto& assistant : mWakeupSettings.get_wakeup_policy_priority()) {
98                                 policy->set_assistant_priority(assistant, ++priority);
99                                 MWR_LOGD("Setting Priority : %d %s", priority, assistant.c_str());
100                         }
101                 }
102         }
103 }
104
105 bool CWakeupManager::initialize()
106 {
107         MWR_LOGE("[ENTER]");
108         std::cerr << "WakeupManager Initialize" << std::endl;
109
110         mPolicyEventObserver.set_wakeup_manager(this);
111         mEngineEventObserver.set_wakeup_manager(this);
112         mAudioEventObserver.set_wakeup_manager(this);
113         mSettingsEventObserver.set_wakeup_manager(this);
114
115         mWakeupSettings.subscribe(&mSettingsEventObserver);
116         mWakeupSettings.initialize();
117
118         mAudioEventObserver.set_wakeup_engine_manager(&mWakeupEngineManager);
119         mAudioManager.subscribe(&mAudioEventObserver);
120         mAudioManager.initialize();
121
122         mWakeupEngineManager.subscribe(&mEngineEventObserver);
123         mWakeupEngineManager.initialize();
124
125         mAssistantConfigManager.initialize();
126
127         mas_dependency_plugin_proxy_interface interface;
128         interface.process_event = wakeup_manager_process_plugin_event;
129         interface.feed_audio_data = wakeup_manager_feed_audio_data;
130         interface.send_command = wakeup_manager_set_dependency_module_command;
131         interface.wakeup_assistant = wakeup_manager_wakeup_assistant;
132
133         dependency_resolver_initialize(interface);
134
135         initialize_wakeup_policy();
136         start_periodic_monitor_timer();
137
138         MWR_LOGD("[END]");
139         return true;
140 }
141
142 bool CWakeupManager::deinitialize()
143 {
144         MWR_LOGE("[ENTER]");
145         std::cerr << "WakeupManager Deinitialize" << std::endl;
146
147         stop_periodic_monitor_timer();
148         stop_streaming_duration_timer();
149
150         dependency_resolver_deinitialize();
151
152         mAssistantConfigManager.deinitialize();
153
154         mWakeupEngineManager.unsubscribe(&mEngineEventObserver);
155         mWakeupEngineManager.deinitialize();
156
157         mAudioManager.unsubscribe(&mAudioEventObserver);
158         mAudioManager.deinitialize();
159
160         mWakeupSettings.deinitialize();
161         mAssistantLanguageInfo.clear();
162
163         MWR_LOGE("[END]");
164         return true;
165 }
166
167 void CWakeupManager::subscribe_wakeup_observer(IWakeupEventObserver *observer)
168 {
169         mWakeupObservers.push_back(observer);
170 }
171
172 void CWakeupManager::unsubscribe_wakeup_observer(IWakeupEventObserver *observer)
173 {
174         auto iter = find(mWakeupObservers.begin(), mWakeupObservers.end(), observer);
175         if (iter != mWakeupObservers.end()) {
176                 mWakeupObservers.erase(iter);
177         }
178 }
179
180 void CWakeupManager::subscribe_setting_observer(ISettingValueObserver* observer)
181 {
182         mSettingObservers.push_back(observer);
183 }
184
185 void CWakeupManager::unsubscribe_setting_observer(ISettingValueObserver* observer)
186 {
187         auto iter = find(mSettingObservers.begin(), mSettingObservers.end(), observer);
188         if (iter != mSettingObservers.end()) {
189                 mSettingObservers.erase(iter);
190         }
191 }
192
193 bool CWakeupManager::activate(void)
194 {
195         MWR_LOGI("[ENTER]");
196
197         if (WAKEUP_MANAGER_STATE_INACTIVE != mWakeupManagerState)
198                 return false;
199
200         /* Activate assistants that supports current voice input language */
201         set_language(mWakeupSettings.get_current_language());
202
203         change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
204         if (mWakeupEngineManager.get_audio_data_required()) {
205                 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
206                 mAudioManager.start_recording(true);
207         }
208
209         MWR_LOGD("[END]");
210         return true;
211 }
212
213 bool CWakeupManager::deactivate(void)
214 {
215         MWR_LOGI("[ENTER]");
216
217         if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
218                 return false;
219
220         mAudioManager.stop_recording(true);
221         mRecordingByVoiceKey = false;
222         change_manager_state(WAKEUP_MANAGER_STATE_INACTIVE);
223
224         stop_streaming_utterance_data();
225         stop_streaming_previous_utterance_data();
226         stop_streaming_follow_up_data();
227
228         MWR_LOGD("[END]");
229         return true;
230 }
231
232 bool CWakeupManager::add_assistant_language(string appid, string language)
233 {
234         MWR_LOGI("[ENTER]");
235         bool found = false;
236         for (auto& info : mAssistantLanguageInfo) {
237                 if(0 == info.appid.compare(appid)) {
238                         info.languageList.push_back(language);
239                         found = true;
240                 }
241         }
242         if(false == found) {
243                 AssistantLanguageInfo info;
244                 info.appid = appid;
245                 info.languageList.push_back(language);
246                 mAssistantLanguageInfo.push_back(info);
247         }
248         if (0 == mCurrentLanguage.compare(language)) {
249                 mAssistantSupportsCurrentLanguage[appid] = true;
250                 if (true == mAssistantEnabled[appid]) {
251                         mWakeupEngineManager.set_assistant_activated(appid, true);
252                 }
253         }
254         MWR_LOGD("[END]");
255         return true;
256 }
257
258 bool CWakeupManager::add_assistant_wakeup_word(string appid, string wakeup_word, string language)
259 {
260         MWR_LOGI("[ENTER]");
261
262         mWakeupEngineManager.engine_add_wakeup_word(appid, wakeup_word, language);
263
264         MWR_LOGD("[END]");
265         return true;
266 }
267
268 bool CWakeupManager::remove_assistant_wakeup_word(string appid, string wakeup_word, string language)
269 {
270         MWR_LOGI("[ENTER]");
271
272         mWakeupEngineManager.engine_remove_wakeup_word(appid, wakeup_word, language);
273
274         MWR_LOGD("[END]");
275         return true;
276 }
277
278 bool CWakeupManager::add_assistant_wakeup_engine(string appid, string engine)
279 {
280         MWR_LOGI("[ENTER] %s %s", appid.c_str(), engine.c_str());
281
282         bool found = false;
283         if (mWakeupSettings.get_multiple_mode()) {
284                 vector<string> assistants = mWakeupSettings.get_enabled_assistants();
285                 auto iter = find(assistants.begin(), assistants.end(), appid);
286                 if (iter != assistants.end())
287                         found = true;
288         } else {
289                 if (0 == appid.compare(mWakeupSettings.get_default_assistant_appid()))
290                         found = true;
291         }
292
293         if (found)
294                 mWakeupEngineManager.engine_add_target_assistant(engine, appid);
295
296         MWR_LOGD("[END]");
297         return true;
298 }
299
300 bool CWakeupManager::set_assistant_language(string appid, string language)
301 {
302         MWR_LOGI("[ENTER] : %s, %s", appid.c_str(), language.c_str());
303
304         mWakeupEngineManager.set_assistant_language(appid, language);
305         mAssistantConfigManager.set_assistant_language(appid, language);
306
307         MWR_LOGD("[END]");
308         return true;
309 }
310
311 bool CWakeupManager::set_assistant_enabled(string appid, bool enabled)
312 {
313         MWR_LOGI("[ENTER]");
314
315         mAssistantEnabled[appid] = enabled;
316         bool activated = enabled;
317         if (false == mAssistantSupportsCurrentLanguage[appid]) {
318                 activated = false;
319         }
320         if (0 == appid.compare(mWakeupSettings.get_default_assistant_appid())) {
321                 activated = true;
322         }
323         mWakeupEngineManager.set_assistant_activated(appid, activated);
324
325         MWR_LOGD("[END]");
326         return true;
327 }
328
329 bool CWakeupManager::set_default_assistant(string appid)
330 {
331         MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
332
333         /* Passing 'expected' as true since MAS is changing the default assistant config */
334         process_default_assistant_changed(appid, true);
335
336         mWakeupSettings.set_default_assistant_appid(appid);
337
338         return true;
339 }
340
341 bool CWakeupManager::process_default_assistant_changed(string appid, bool expected)
342 {
343         MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
344
345         if (mCurrentDefaultAssistant.compare(appid) == 0) {
346                 MWR_LOGE("Default assistant appid not changed, ignoring...");
347                 return false;
348         }
349
350         if (mWakeupManagerState == WAKEUP_MANAGER_STATE_UTTERANCE ||
351                 mWakeupManagerState == WAKEUP_MANAGER_STATE_PROCESSING) {
352                 if (expected) {
353                         stop_streaming_utterance_data();
354                         stop_streaming_previous_utterance_data();
355                         stop_streaming_follow_up_data();
356
357                         mWakeupEngineManager.update_recognition_result(appid, MA_RECOGNITION_RESULT_EVENT_ERROR);
358                 } else {
359                         /* If this is an unexpected change, invalidate previous recognition process */
360                         update_recognition_result(mCurrentDefaultAssistant, MA_RECOGNITION_RESULT_EVENT_ERROR);
361                 }
362         }
363
364         /* Check if previous default assistant has to be deactivated */
365         bool activated = true;
366         if (false == mAssistantSupportsCurrentLanguage[mCurrentDefaultAssistant]) {
367                 activated = false;
368         }
369         if (false == mAssistantEnabled[mCurrentDefaultAssistant]) {
370                 activated = false;
371         }
372         mWakeupEngineManager.set_assistant_activated(mCurrentDefaultAssistant, activated);
373
374         /* New default assistant has to be activated no matter what */
375         mWakeupEngineManager.set_assistant_activated(appid, true);
376
377         mCurrentDefaultAssistant = appid;
378
379         MWR_LOGD("[END]");
380         return true;
381 }
382
383 string CWakeupManager::get_default_assistant()
384 {
385         return mWakeupSettings.get_default_assistant_appid();
386 }
387
388 bool CWakeupManager::get_assistant_enabled(string appid)
389 {
390         return mAssistantEnabled[appid];
391 }
392
393 bool CWakeupManager::set_language(string language)
394 {
395         bool valid = false;
396         MWR_LOGI("[ENTER] : %s", language.c_str());
397
398         if (check_language_valid(language)) {
399                 mCurrentLanguage = language;
400                 valid = true;
401         } else {
402                 MWR_LOGE("[ERROR] Invalid language (%s)", language.c_str());
403         }
404
405         for (auto& info : mAssistantLanguageInfo) {
406                 bool disable = false;
407                 if (valid) {
408                         bool supported = false;
409                         if (info.languageList.end() !=
410                                 find(info.languageList.begin(), info.languageList.end(), language)) {
411                                 supported = true;
412                         }
413                         mAssistantSupportsCurrentLanguage[info.appid] = supported;
414                         /* Disable this assistant if language not supported */
415                         if (!supported) disable = true;
416                 } else {
417                         /* If current language is not valid, assume all languages support it */
418                         mAssistantSupportsCurrentLanguage[info.appid] = true;
419                 }
420
421                 if (false == mAssistantEnabled[info.appid]) {
422                         disable = true;
423                 }
424                 if (0 == info.appid.compare(mWakeupSettings.get_default_assistant_appid())) {
425                         /* Default Assistant should be activated no matter what */
426                         disable = false;
427                 }
428                 mWakeupEngineManager.set_assistant_activated(info.appid, !disable);
429                 std::string assistant_language;
430                 int ret = mAssistantConfigManager.get_assistant_language(info.appid, assistant_language);
431                 if (0 != ret || !check_language_valid(assistant_language)) {
432                         mWakeupEngineManager.set_assistant_language(info.appid, language);
433                 } else {
434                         mWakeupEngineManager.set_assistant_language(info.appid, assistant_language);
435                 }
436         }
437
438         MWR_LOGD("[END]");
439         return valid;
440 }
441
442 bool CWakeupManager::get_recording_by_voice_key()
443 {
444         return mRecordingByVoiceKey;
445 }
446
447 void CWakeupManager::set_recording_by_voice_key(bool recording)
448 {
449         mRecordingByVoiceKey = recording;
450 }
451
452 STREAMING_MODE CWakeupManager::get_streaming_mode()
453 {
454         return mStreamingMode;
455 }
456
457 bool CWakeupManager::set_streaming_mode(STREAMING_MODE mode)
458 {
459         lock_guard<mutex> lock(mMutex);
460         mStreamingMode = mode;
461         return true;
462 }
463
464 bool CWakeupManager::change_manager_state(wakeup_manager_state_e state)
465 {
466         MWR_LOGI("[ENTER] : %d", state);
467         mWakeupManagerState = state;
468         mWakeupEngineManager.update_manager_state(state);
469         for (const auto& observer : mWakeupObservers) {
470                 observer->on_wakeup_service_state_changed((ma_service_state_e)state);
471         }
472         return true;
473 }
474
475 wakeup_manager_state_e CWakeupManager::get_manager_state()
476 {
477         return mWakeupManagerState;
478 }
479
480 bool CWakeupManager::update_voice_feedback_state(string appid, bool state)
481 {
482         MWR_LOGI("[ENTER]");
483
484         if (state) {
485                 if (WAKEUP_MANAGER_STATE_LISTENING == mWakeupManagerState ||
486                         WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState) {
487                         change_manager_state(WAKEUP_MANAGER_STATE_VOICE_FEEDBACK);
488                 }
489         } else {
490                 if (WAKEUP_MANAGER_STATE_VOICE_FEEDBACK == mWakeupManagerState) {
491                         change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
492                 }
493         }
494
495         MWR_LOGD("[END]");
496         return true;
497 }
498
499 bool CWakeupManager::set_assistant_specific_command(string appid, string command)
500 {
501         MWR_LOGI("[ENTER]");
502
503         /*
504         static const string voice_key_pressed{"voice_key_pressed"};
505         static const string voice_key_released{"voice_key_released"};
506
507         if (0 == command.compare(voice_key_pressed)) {
508                 process_event(MA_PLUGIN_EVENT_VOICE_KEY_PRESSED, NULL, 0);
509         } else if (0 == command.compare(voice_key_released)) {
510                 process_event(MA_PLUGIN_EVENT_VOICE_KEY_RELEASED, NULL, 0);
511         }
512         */
513
514         mWakeupEngineManager.engine_set_assistant_specific_command(appid, command);
515
516         MWR_LOGD("[END]");
517         return true;
518 }
519
520 bool CWakeupManager::set_background_volume(string appid, double ratio)
521 {
522         MWR_LOGD("[DEBUG] set background volume (%f)", ratio);
523
524         int ret = 0;
525         mAudioManager.set_background_volume(ratio);
526         return ret;
527 }
528
529 bool CWakeupManager::update_recognition_result(string appid, int result)
530 {
531         MWR_LOGI("[ENTER]");
532
533         stop_streaming_utterance_data();
534         stop_streaming_previous_utterance_data();
535         stop_streaming_follow_up_data();
536
537         mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
538         mWakeupEngineManager.update_recognition_result(appid, result);
539         if (WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState ||
540                 WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
541                 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
542         }
543         MWR_LOGD("[END]");
544         return true;
545 }
546
547 static long long get_current_milliseconds_after_epoch()
548 {
549         auto now = chrono::steady_clock::now();
550         auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
551         /* number of milliseconds since the epoch of system_clock */
552         auto value = now_ms.time_since_epoch();
553
554         return value.count();
555 }
556
557 bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len)
558 {
559         MWR_LOGE("[ENTER] : %d", event);
560         if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
561                 return false;
562
563         bool start_recording = false;
564         bool stop_recording = false;
565
566         boost::optional<ma_voice_key_status_e> next_voice_key_status;
567         if (MAS_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) {
568                 if (STREAMING_MODE::FOLLOW_UP == mStreamingMode) {
569                         MWR_LOGE("Voice key pressed, but currently streaming follow_up audio");
570                 } else {
571                         if (VOICE_KEY_SUPPORT_MODE_NONE != mCurrentVoiceKeySupportMode) {
572                                 start_recording = true;
573                         }
574                 }
575                 next_voice_key_status = MA_VOICE_KEY_STATUS_PRESSED;
576         } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) {
577                 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode ||
578                         VOICE_KEY_SUPPORT_MODE_ALL == mCurrentVoiceKeySupportMode) {
579                         stop_recording = true;
580                 }
581                 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH;
582         } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
583                 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode) {
584                         stop_recording = true;
585                 }
586                 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP;
587         }
588
589         if (start_recording) {
590                 mRecordingByVoiceKey = true;
591
592                 mAudioManager.stop_recording(true);
593
594                 stop_streaming_utterance_data();
595                 stop_streaming_previous_utterance_data();
596                 stop_streaming_follow_up_data();
597
598                 mAudioManager.clear_audio_data();
599                 change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
600
601                 /* Start recorder thread using appropriate recording device */
602                 mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
603                 mAudioManager.start_recording(true);
604
605                 /* Wakeup default assistant */
606                 /* TODO: apply conversation timeout for selecting assistant here */
607                 mas_wakeup_event_info wakeup_info;
608                 initialize_wakeup_event_info(&wakeup_info);
609                 /* Make sure to use background data */
610                 wakeup_info.wakeup_time_valid = true;
611                 wakeup_info.wakeup_end_time = get_current_milliseconds_after_epoch();
612                 wakeup_info.wakeup_engine = WAKEUP_ENGINE_VOICE_KEY;
613
614                 std::string default_assistant_appid = mWakeupSettings.get_default_assistant_appid();
615                 wakeup_info.wakeup_appid = default_assistant_appid.c_str();
616                 MWR_LOGD("wakeup_appid : %s", wakeup_info.wakeup_appid);
617
618                 set_last_wakeup_event_info(wakeup_info);
619                 mWakeupEngineManager.set_selected_wakeup_info(wakeup_info);
620                 for (const auto& observer : mWakeupObservers) {
621                         observer->on_wakeup(wakeup_info);
622                 }
623         }
624         if (stop_recording) {
625                 mRecordingByVoiceKey = false;
626
627                 stop_streaming_duration_timer();
628                 mAudioManager.finalize_audio_data();
629
630                 if (STREAMING_MODE::UTTERANCE == mStreamingMode) {
631                         change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
632                 } else {
633                         change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
634                 }
635
636                 mAudioManager.stop_recording(true);
637                 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
638                 if (mWakeupEngineManager.get_audio_data_required()) {
639                         /* Restart recorder thread using appropriate recording device */
640                         mAudioManager.start_recording(true);
641                 }
642         }
643
644         if (next_voice_key_status) {
645                 for (const auto& observer : mWakeupObservers) {
646                         observer->on_voice_key_status_changed(*next_voice_key_status);
647                 }
648         }
649
650         MWR_LOGD("[END]");
651         return true;
652 }
653
654 vector<IWakeupEventObserver*> CWakeupManager::get_wakeup_observers()
655 {
656         return mWakeupObservers;
657 }
658
659 void CWakeupManager::set_last_wakeup_event_info(mas_wakeup_event_info wakeup_info)
660 {
661         mLastWakeupEventInfo = wakeup_info;
662 }
663
664 vector<ISettingValueObserver*> CWakeupManager::get_setting_observers()
665 {
666         return mSettingObservers;
667 }
668
669 static Eina_Bool streaming_duration_expired(void *data)
670 {
671         MWR_LOGW("[ENTER]");
672         CWakeupManager *wakeup_manager = static_cast<CWakeupManager*>(data);
673         if (nullptr == wakeup_manager) return ECORE_CALLBACK_CANCEL;
674
675         wakeup_manager->set_streaming_duration_timer(nullptr);
676
677         CAudioManager *audio_manager = wakeup_manager->get_audio_manager();
678         CWakeupEngineManager *engine_manager = wakeup_manager->get_engine_manager();
679
680         if (nullptr == audio_manager) return ECORE_CALLBACK_CANCEL;
681         if (nullptr == engine_manager) return ECORE_CALLBACK_CANCEL;
682
683         switch(wakeup_manager->get_streaming_mode()) {
684                 case STREAMING_MODE::UTTERANCE:
685                         audio_manager->stop_streaming_current_utterance_data();
686                         engine_manager->stop_streaming_current_utterance_data();
687                 break;
688                 case STREAMING_MODE::PREVIOUS_UTTERANCE:
689                         audio_manager->stop_streaming_previous_utterance_data();
690                 break;
691                 case STREAMING_MODE::FOLLOW_UP:
692                         audio_manager->stop_streaming_follow_up_data();
693                         audio_manager->stop_recording(true);
694                         wakeup_manager->set_recording_by_voice_key(false);
695                         audio_manager->clear_audio_data();
696                 break;
697         }
698
699         wakeup_manager->set_streaming_mode(STREAMING_MODE::NONE);
700
701         if (WAKEUP_MANAGER_STATE_UTTERANCE == wakeup_manager->get_manager_state()) {
702                 audio_manager->stop_recording(true);
703                 wakeup_manager->set_recording_by_voice_key(false);
704                 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
705                 if (engine_manager->get_audio_data_required()) {
706                         /* Restart recorder thread using appropriate recording device */
707                         audio_manager->start_recording(true);
708                 }
709                 wakeup_manager->change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
710         }
711
712         return ECORE_CALLBACK_CANCEL;
713 }
714
715 bool CWakeupManager::start_streaming_utterance_data()
716 {
717         MWR_LOGI("[ENTER]");
718
719         mAudioManager.stop_streaming_current_utterance_data();
720         mWakeupEngineManager.stop_streaming_current_utterance_data();
721
722         mStreamingMode = STREAMING_MODE::UTTERANCE;
723
724         bool streaming_by_manager = true;
725         if (false == mLastWakeupEventInfo.wakeup_time_valid) {
726                 mWakeupEngineManager.start_streaming_current_utterance_data();
727                 streaming_by_manager = false;
728         } else {
729                 mAudioManager.start_streaming_current_utterance_data(mLastWakeupEventInfo.wakeup_end_time);
730         }
731
732         stop_streaming_duration_timer();
733         if (streaming_by_manager) {
734                 start_streaming_duration_timer();
735         }
736
737         MWR_LOGD("[END]");
738         return true;
739 }
740
741 bool CWakeupManager::stop_streaming_utterance_data()
742 {
743         MWR_LOGI("[ENTER]");
744
745         if (STREAMING_MODE::UTTERANCE != mStreamingMode) return false;
746
747         mAudioManager.stop_streaming_current_utterance_data();
748         mWakeupEngineManager.stop_streaming_current_utterance_data();
749
750         if (mStreamingDurationTimer) {
751                 stop_streaming_duration_timer();
752         }
753         if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
754                 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
755                 mAudioManager.stop_recording(true);
756                 mRecordingByVoiceKey = false;
757                 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
758                 if (mWakeupEngineManager.get_audio_data_required()) {
759                         /* Restart recorder thread using appropriate recording device */
760                         mAudioManager.start_recording(true);
761                 }
762         }
763
764         mStreamingMode = STREAMING_MODE::NONE;
765
766         MWR_LOGD("[END]");
767         return true;
768 }
769
770 bool CWakeupManager::start_streaming_follow_up_data()
771 {
772         MWR_LOGI("[ENTER]");
773
774         mAudioManager.stop_streaming_follow_up_data();
775         mWakeupEngineManager.stop_streaming_current_utterance_data();
776
777         mStreamingMode = STREAMING_MODE::FOLLOW_UP;
778
779         /* For the follow up streaming, audio data should be recorded from now on */
780         mAudioManager.stop_recording(true);
781         mAudioManager.clear_audio_data();
782         change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
783         mAudioManager.set_recording_session(RECORDING_SESSION_FOLLOW_UP);
784         mAudioManager.start_recording(true);
785
786         mAudioManager.start_streaming_follow_up_data();
787
788         stop_streaming_duration_timer();
789         start_streaming_duration_timer();
790
791         MWR_LOGD("[END]");
792         return true;
793 }
794
795 bool CWakeupManager::stop_streaming_follow_up_data()
796 {
797         MWR_LOGI("[ENTER]");
798         if (STREAMING_MODE::FOLLOW_UP != mStreamingMode) return false;
799
800         mAudioManager.stop_streaming_follow_up_data();
801         mWakeupEngineManager.stop_streaming_current_utterance_data();
802
803         if (mStreamingDurationTimer) {
804                 stop_streaming_duration_timer();
805         }
806
807         if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
808                 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
809                 mAudioManager.stop_recording(true);
810                 mRecordingByVoiceKey = false;
811                 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
812                 if (mWakeupEngineManager.get_audio_data_required()) {
813                         /* Restart recorder thread using appropriate recording device */
814                         mAudioManager.start_recording(true);
815                 }
816         }
817
818         mStreamingMode = STREAMING_MODE::NONE;
819
820         mAudioManager.clear_audio_data();
821
822         MWR_LOGD("[END]");
823         return true;
824 }
825
826 bool CWakeupManager::start_streaming_previous_utterance_data()
827 {
828         MWR_LOGI("[ENTER]");
829
830         mAudioManager.stop_streaming_previous_utterance_data();
831         mWakeupEngineManager.stop_streaming_current_utterance_data();
832
833         mStreamingMode = STREAMING_MODE::PREVIOUS_UTTERANCE;
834         mAudioManager.start_streaming_previous_utterance_data();
835
836         stop_streaming_duration_timer();
837         start_streaming_duration_timer();
838
839         MWR_LOGD("[END]");
840         return true;
841 }
842
843 bool CWakeupManager::stop_streaming_previous_utterance_data()
844 {
845         MWR_LOGI("[ENTER]");
846         if (STREAMING_MODE::PREVIOUS_UTTERANCE != mStreamingMode) return false;
847
848         mAudioManager.stop_streaming_previous_utterance_data();
849         mWakeupEngineManager.stop_streaming_current_utterance_data();
850
851         if (mStreamingDurationTimer) {
852                 stop_streaming_duration_timer();
853         }
854
855         if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
856                 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
857         }
858
859         mStreamingMode = STREAMING_MODE::NONE;
860
861         MWR_LOGD("[END]");
862         return true;
863 }
864
865 bool CWakeupManager::get_audio_format(int* rate, int* channel, int* audio_type)
866 {
867         MWR_LOGI("[ENTER]");
868
869         if (!audio_type || !rate || !channel) {
870                 MWR_LOGE("[ERROR] Invalid parameter");
871                 return false;
872         }
873
874         dependency_resolver_get_audio_format(rate, channel, audio_type);
875
876         MWR_LOGD("[END] rate(%d), channel(%d), audio_type(%d)", *rate, *channel, *audio_type);
877         return true;
878 }
879
880 bool CWakeupManager::get_audio_source_type(char** type)
881 {
882         MWR_LOGI("[ENTER]");
883
884         if (!type) {
885                 MWR_LOGE("[ERROR] Invalid parameter");
886                 return false;
887         }
888
889         dependency_resolver_get_audio_source_type(type);
890
891         MWR_LOGD("[END] type(%s)", *type);
892         return true;
893 }
894
895 bool CWakeupManager::set_wake_word_audio_require_flag(bool require)
896 {
897         MWR_LOGI("[ENTER]");
898
899         mWakeupEngineManager.set_wake_word_audio_require_flag(require);
900
901         MWR_LOGD("[END]");
902         return true;
903 }
904
905 bool CWakeupManager::set_voice_key_tap_duration(float duration)
906 {
907         MWR_LOGI("[ENTER]");
908
909         dependency_resolver_set_voice_key_tap_duration(duration);
910
911         MWR_LOGD("[END]");
912         return true;
913 }
914
915 bool CWakeupManager::unset_voice_key_tap_duration()
916 {
917         MWR_LOGI("[ENTER]");
918
919         dependency_resolver_unset_voice_key_tap_duration();
920
921         MWR_LOGD("[END]");
922         return true;
923 }
924
925 bool CWakeupManager::set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE mode)
926 {
927         MWR_LOGI("Voice key support mode : %d", mode);
928         mCurrentVoiceKeySupportMode = mode;
929
930         char* support_mode = NULL;
931         switch (mode)
932         {
933         case VOICE_KEY_SUPPORT_MODE_NONE:
934                 support_mode = strdup("none");
935                 break;
936         case VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK:
937                 support_mode = strdup("push_to_talk");
938                 break;
939         case VOICE_KEY_SUPPORT_MODE_TAP_TO_TALK:
940                 support_mode = strdup("tap_to_talk");
941                 break;
942         case VOICE_KEY_SUPPORT_MODE_ALL:
943                 support_mode = strdup("all");
944                 break;
945         default:
946                 support_mode = strdup("none");
947                 break;
948         }
949
950         dependency_resolver_set_voice_key_support_mode(support_mode);
951
952         if (support_mode)
953                 free(support_mode);
954
955         return true;
956 }
957
958 CWakeupPolicy* CWakeupManager::get_wakeup_policy()
959 {
960         return mWakeupPolicy.get();
961 }
962
963 CWakeupEngineManager* CWakeupManager::get_engine_manager()
964 {
965         return &mWakeupEngineManager;
966 }
967
968 CAudioManager* CWakeupManager::get_audio_manager()
969 {
970         return &mAudioManager;
971 }
972
973 CWakeupSettings* CWakeupManager::get_wakeup_settings()
974 {
975         return &mWakeupSettings;
976 }
977
978 void CWakeupManager::feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len)
979 {
980         const std::chrono::seconds interval(5);
981         static auto last = std::chrono::steady_clock::now();
982         auto now = std::chrono::steady_clock::now();
983         if (now - last > interval) {
984                 std::cerr << "Feeding Audio : " << len << std::endl;
985                 last = now;
986         }
987
988         mAudioManager.feed_audio_data(event, buffer, len);
989 }
990
991 void CWakeupManager::set_dependency_module_command(string engine_name, string command)
992 {
993         mWakeupEngineManager.engine_set_dependency_module_command(engine_name, command);
994 }
995
996 static Eina_Bool periodic_monitor_func(void *data)
997 {
998         std::cerr << "MAS PERIODIC HEALTH CHECK" << std::endl;
999         return ECORE_CALLBACK_RENEW;
1000 }
1001
1002 void CWakeupManager::start_periodic_monitor_timer()
1003 {
1004         MWR_LOGI("MONITOR_TIMER START");
1005         mPeriodicMonitorTimer = ecore_timer_add(
1006                 30.0f,
1007                 periodic_monitor_func, nullptr);
1008 }
1009
1010 void CWakeupManager::stop_periodic_monitor_timer()
1011 {
1012         if (mPeriodicMonitorTimer) {
1013                 ecore_timer_del(mPeriodicMonitorTimer);
1014                 mPeriodicMonitorTimer = nullptr;
1015         }
1016 }
1017
1018 void CWakeupManager::start_streaming_duration_timer()
1019 {
1020         MWR_LOGI("DURATION_TIMER START");
1021         ecore_main_loop_thread_safe_call_async([](void* data) {
1022                 MWR_LOGI("DURATION_TIMER START - async");
1023                 CWakeupManager* manager = static_cast<CWakeupManager*>(data);
1024                 if (!manager) return;
1025
1026                 CWakeupSettings *settings = manager->get_wakeup_settings();
1027                 if (settings) {
1028                         Ecore_Timer* timer = ecore_timer_add(
1029                                 settings->get_streaming_duration_max(),
1030                                 streaming_duration_expired, manager);
1031                         manager->set_streaming_duration_timer(timer);
1032                         MWR_LOGI("DURATION_TIMER STARTED : %p", timer);
1033                 }
1034         }, this);
1035 }
1036
1037 void CWakeupManager::stop_streaming_duration_timer()
1038 {
1039         MWR_LOGI("DURATION_TIMER STOP");
1040         if (mStreamingDurationTimer) {
1041                 MWR_LOGI("DURATION_TIMER STOP - has timer");
1042                 ecore_main_loop_thread_safe_call_async([](void* data) {
1043                         MWR_LOGI("DURATION_TIMER STOP - async");
1044                         CWakeupManager* manager = static_cast<CWakeupManager*>(data);
1045                         if (!manager) return;
1046
1047                         Ecore_Timer* timer = manager->get_streaming_duration_timer();
1048                         void* ret = ecore_timer_del(timer);
1049                         MWR_LOGI("DURATION_TIMER EXISTS : %p %p", timer, ret);
1050                         manager->set_streaming_duration_timer(nullptr);
1051                 }, this);
1052         }
1053 }
1054
1055 void CWakeupManager::set_streaming_duration_timer(Ecore_Timer* timer)
1056 {
1057         MWR_LOGI("DURATION_TIMER SET : %p", timer);
1058         mStreamingDurationTimer = timer;
1059 }
1060
1061 Ecore_Timer* CWakeupManager::get_streaming_duration_timer()
1062 {
1063         return mStreamingDurationTimer;
1064 }
1065
1066 bool CWakeupManager::CEngineEventObserver::on_wakeup_event(string engine_name, mas_wakeup_event_info wakeup_info)
1067 {
1068         MWR_LOGI("[ENTER]");
1069         if (nullptr == mWakeupManager) return false;
1070         if (nullptr == wakeup_info.wakeup_appid) return false;
1071
1072         if (0 != mWakeupManager->get_default_assistant().compare(wakeup_info.wakeup_appid)) {
1073                 if (false == mWakeupManager->get_assistant_enabled(string{wakeup_info.wakeup_appid})) {
1074                         MWR_LOGE("Wakeup event with deactivated appid : %s", wakeup_info.wakeup_appid);
1075                         return false;
1076                 }
1077         }
1078
1079         CWakeupPolicy* policy = mWakeupManager->get_wakeup_policy();
1080         if (policy) {
1081                 policy->wakeup_candidate(wakeup_info);
1082         }
1083         return true;
1084 }
1085
1086 bool CWakeupManager::CEngineEventObserver::on_speech_status(string engine_name, mas_speech_status_e status)
1087 {
1088         MWR_LOGI("[ENTER]");
1089         if (nullptr == mWakeupManager) return false;
1090
1091         return true;
1092 }
1093
1094 bool CWakeupManager::CEngineEventObserver::on_error(string engine_name, int error_code, string error_message)
1095 {
1096         MWR_LOGI("[ENTER]");
1097         if (nullptr == mWakeupManager) return false;
1098
1099         return true;
1100 }
1101
1102 bool CWakeupManager::CEngineEventObserver::on_audio_data_require_status(string engine_name, bool require)
1103 {
1104         MWR_LOGI("[ENTER]");
1105         if (nullptr == mWakeupManager) return false;
1106         if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManager->get_manager_state()) return false;
1107
1108         CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1109         CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1110
1111         if (audio_manager && engine_manager) {
1112                 if (engine_manager->get_audio_data_required()) {
1113                         if (mWakeupManager->get_recording_by_voice_key() != true) {
1114                                 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
1115                                 audio_manager->start_recording(true);
1116                         }
1117                 } else {
1118                         if (mWakeupManager->get_recording_by_voice_key() != true) {
1119                                 audio_manager->stop_recording(true);
1120                         }
1121                 }
1122         }
1123         return true;
1124 }
1125
1126 bool CWakeupManager::CEngineEventObserver::on_streaming_audio_data(
1127         mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1128 {
1129         if (nullptr == mWakeupManager) return false;
1130
1131         vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1132         for (const auto& observer : observers) {
1133                 observer->on_streaming_audio_data(event, buffer, len);
1134         }
1135
1136         return true;
1137 }
1138
1139 bool CWakeupManager::CEngineEventObserver::on_audio_streaming_data_section(
1140         ma_audio_streaming_data_section_e section)
1141 {
1142         if (nullptr == mWakeupManager) return false;
1143
1144         vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1145         for (const auto& observer : observers) {
1146                 observer->on_audio_streaming_data_section(section);
1147         }
1148
1149         return true;
1150 }
1151
1152 bool CWakeupManager::CEngineEventObserver::on_wakeup_engine_command(
1153         mas_wakeup_engine_command_target_e target, string engine_name, string assistant_name, string command)
1154 {
1155         if (nullptr == mWakeupManager) return false;
1156
1157         if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_DEPENDENCY_MODULE == target) {
1158                 dependency_resolver_process_wakeup_engine_command(engine_name.c_str(), command.c_str());
1159         }
1160
1161         if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_ALL_ASSISTANTS == target ||
1162                 MAS_WAKEUP_ENGINE_COMMAND_TARGET_SPECIFIC_ASSISTANT == target) {
1163                 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1164                 for (const auto& observer : observers) {
1165                         observer->on_wakeup_engine_command(target, assistant_name.c_str(), command.c_str());
1166                 }
1167         }
1168
1169         return true;
1170 }
1171
1172 void CWakeupManager::CPolicyEventObserver::on_wakeup(mas_wakeup_event_info wakeup_info)
1173 {
1174         if (nullptr == mWakeupManager) return;
1175
1176         CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1177         CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1178         CWakeupSettings* settings = mWakeupManager->get_wakeup_settings();
1179         if (nullptr == audio_manager || nullptr == engine_manager || nullptr == settings) return;
1180
1181         if (wakeup_info.wakeup_appid && strlen(wakeup_info.wakeup_appid) > 0) {
1182                 mWakeupManager->set_default_assistant(wakeup_info.wakeup_appid);
1183         }
1184
1185         mWakeupManager->stop_streaming_utterance_data();
1186         mWakeupManager->stop_streaming_previous_utterance_data();
1187         mWakeupManager->stop_streaming_follow_up_data();
1188         mWakeupManager->change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
1189
1190         mWakeupManager->set_last_wakeup_event_info(wakeup_info);
1191         engine_manager->set_selected_wakeup_info(wakeup_info);
1192         vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1193         for (const auto& observer : observers) {
1194                 observer->on_wakeup(wakeup_info);
1195         }
1196
1197         audio_manager->set_recording_session(RECORDING_SESSION_UTTERANCE);
1198 }
1199
1200 bool CWakeupManager::CAudioEventObserver::on_recording_audio_data(long time, void* data, int len)
1201 {
1202         if (nullptr == mWakeupManager) return false;
1203         if (nullptr == mEngineManager) return false;
1204
1205         if (false == mEngineManager->get_audio_data_required()) return false;
1206
1207         if (mWakeupManager->get_recording_by_voice_key() != true) {
1208                 /* When follow-up streaming in progress, no need to feed audio data to wakeup engines */
1209                 if (STREAMING_MODE::FOLLOW_UP != mWakeupManager->get_streaming_mode()) {
1210                         mEngineManager->engine_feed_audio_data(time, data, len);
1211                 }
1212         }
1213
1214         return true;
1215 }
1216
1217 bool CWakeupManager::CAudioEventObserver::on_streaming_audio_data(
1218         mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1219 {
1220         if (nullptr == mWakeupManager) return false;
1221
1222         vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1223         for (const auto& observer : observers) {
1224                 observer->on_streaming_audio_data(event, buffer, len);
1225         }
1226         if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
1227                 mWakeupManager->set_streaming_mode(STREAMING_MODE::NONE);
1228                 mWakeupManager->stop_streaming_duration_timer();
1229         }
1230
1231         return true;
1232 }
1233
1234 bool CWakeupManager::CSettingsEventObserver::on_voice_input_language_changed(
1235         const char* language)
1236 {
1237         if (nullptr == mWakeupManager || nullptr == language) return false;
1238         mWakeupManager->set_language(std::string(language));
1239         vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1240         for (const auto& observer : observers) {
1241                 observer->on_value_changed();
1242         }
1243         return true;
1244 }
1245
1246 bool CWakeupManager::CSettingsEventObserver::on_assistant_enabled_info_changed(
1247         const char* appid, bool enabled)
1248 {
1249         if (nullptr == mWakeupManager || nullptr == appid) return false;
1250         mWakeupManager->set_assistant_enabled(std::string(appid), enabled);
1251         vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1252         for (const auto& observer : observers) {
1253                 if (mWakeupManager->get_wakeup_settings()->get_multiple_mode())
1254                         observer->on_loaded_wakeup_engine_changed();
1255                 else
1256                         observer->on_value_changed();
1257         }
1258         return true;
1259 }
1260
1261 bool CWakeupManager::CSettingsEventObserver::on_default_assistant_appid_changed(
1262         const char* appid)
1263 {
1264         if (nullptr == mWakeupManager || nullptr == appid) return false;
1265         /* Passing 'expected' as false since the change was occurred outside of MAS */
1266         mWakeupManager->process_default_assistant_changed(std::string(appid), false);
1267         vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1268         for (const auto& observer : observers) {
1269                 if (mWakeupManager->get_wakeup_settings()->get_multiple_mode())
1270                         observer->on_value_changed();
1271                 else
1272                         observer->on_loaded_wakeup_engine_changed();
1273         }
1274         return true;
1275 }
1276
1277 bool CWakeupManager::CSettingsEventObserver::on_multiple_mode_changed()
1278 {
1279         if (nullptr == mWakeupManager) return false;
1280         vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1281         for (const auto& observer : observers) {
1282                 observer->on_loaded_wakeup_engine_changed();
1283         }
1284         return true;
1285 }
1286
1287 } // wakeup
1288 } // multiassistant