diff options
-rw-r--r-- | inc/service_main.h | 2 | ||||
-rw-r--r-- | org.tizen.multi-assistant-service.xml | 2 | ||||
-rw-r--r-- | packaging/org.tizen.multi-assistant-service.spec | 2 | ||||
-rw-r--r-- | plugins/wakeup-manager/dependency-default/src/dependency_default_audio.cpp | 2 | ||||
-rw-r--r-- | plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp | 12 | ||||
-rw-r--r-- | plugins/wakeup-manager/inc/wakeup_audio_manager.h | 2 | ||||
-rw-r--r-- | plugins/wakeup-manager/inc/wakeup_engine_manager.h | 8 | ||||
-rw-r--r-- | plugins/wakeup-manager/inc/wakeup_manager.h | 3 | ||||
-rw-r--r-- | plugins/wakeup-manager/src/wakeup_audio_manager.cpp | 31 | ||||
-rw-r--r-- | plugins/wakeup-manager/src/wakeup_engine_manager.cpp | 35 | ||||
-rw-r--r-- | plugins/wakeup-manager/src/wakeup_manager.cpp | 26 | ||||
-rw-r--r-- | src/service_config.cpp | 31 | ||||
-rw-r--r-- | src/service_ipc_dbus.cpp | 40 | ||||
-rw-r--r-- | src/service_main.cpp | 104 |
14 files changed, 239 insertions, 61 deletions
diff --git a/inc/service_main.h b/inc/service_main.h index cf947e6..168b59f 100644 --- a/inc/service_main.h +++ b/inc/service_main.h @@ -193,6 +193,8 @@ private: IApplicationManager& mApplicationManager; IPreferenceManager& mPreferenceManager; + + pid_t mLastDuckingRequester{-1}; }; #endif /* __SERVICE_MAIN_H__ */ diff --git a/org.tizen.multi-assistant-service.xml b/org.tizen.multi-assistant-service.xml index b6d8d33..1a2bee4 100644 --- a/org.tizen.multi-assistant-service.xml +++ b/org.tizen.multi-assistant-service.xml @@ -1,5 +1,5 @@ <?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.3.22"> +<manifest xmlns="http://tizen.org/ns/packages" api-version="5.0" package="org.tizen.multi-assistant-service" version="0.3.26"> <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> diff --git a/packaging/org.tizen.multi-assistant-service.spec b/packaging/org.tizen.multi-assistant-service.spec index 0b54e16..61bffe2 100644 --- a/packaging/org.tizen.multi-assistant-service.spec +++ b/packaging/org.tizen.multi-assistant-service.spec @@ -1,6 +1,6 @@ Name: org.tizen.multi-assistant-service Summary: Multi assistant service -Version: 0.3.22 +Version: 0.3.26 Release: 1 Group: Graphics & UI Framework/Voice Framework License: Flora-1.1 diff --git a/plugins/wakeup-manager/dependency-default/src/dependency_default_audio.cpp b/plugins/wakeup-manager/dependency-default/src/dependency_default_audio.cpp index 9f59d08..78b5195 100644 --- a/plugins/wakeup-manager/dependency-default/src/dependency_default_audio.cpp +++ b/plugins/wakeup-manager/dependency-default/src/dependency_default_audio.cpp @@ -338,6 +338,7 @@ void dependency_default_audio_voice_key_pressed_set(bool pressed) void dependency_default_audio_set_background_volume(double ratio) { + LOGD("[ENTER]"); int ret; if (ratio >= 0.5) { @@ -386,6 +387,7 @@ void dependency_default_audio_set_background_volume(double ratio) } } } + LOGD("[EXIT]"); } void dependency_default_audio_get_audio_format(int* rate, int* channel, int* audio_type) diff --git a/plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp b/plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp index 140ac41..0b0c856 100644 --- a/plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp +++ b/plugins/wakeup-manager/dependency-default/src/dependency_default_button.cpp @@ -16,6 +16,8 @@ static mas_dependency_plugin_proxy_interface g_proxy_interface; static Ecore_Event_Handler* g_key_down_handler = NULL; static Ecore_Event_Handler* g_key_up_handler = NULL; +static Ecore_Wl2_Display *g_ecore_wl2_display = NULL; + static chrono::time_point<chrono::system_clock> g_last_key_pressed; static bool g_voice_key_pressed = false; const float DEFAULT_KEY_TAP_DURATION = 0.3f * 1000; @@ -133,13 +135,11 @@ void dependency_default_button_initialize(mas_dependency_plugin_proxy_interface { g_proxy_interface = interface; - Ecore_Wl2_Display *_ecore_wl2_display = NULL; - Eina_Bool ret = ecore_wl2_init(); LOGD("ecore_wl2_init: %d", ret); - _ecore_wl2_display = ecore_wl2_display_connect(NULL); - LOGD("_ecore_wl2_display: %p", _ecore_wl2_display); + g_ecore_wl2_display = ecore_wl2_display_connect(NULL); + LOGD("g_ecore_wl2_display: %p", g_ecore_wl2_display); g_last_key_pressed = chrono::system_clock::now(); _grab_voice_key(); @@ -148,6 +148,10 @@ void dependency_default_button_initialize(mas_dependency_plugin_proxy_interface void dependency_default_button_deinitialize() { + if (g_ecore_wl2_display) { + ecore_wl2_display_disconnect(g_ecore_wl2_display); + g_ecore_wl2_display = NULL; + } _delete_key_cb(); _ungrab_voice_key(); } diff --git a/plugins/wakeup-manager/inc/wakeup_audio_manager.h b/plugins/wakeup-manager/inc/wakeup_audio_manager.h index 16d4059..7165ce3 100644 --- a/plugins/wakeup-manager/inc/wakeup_audio_manager.h +++ b/plugins/wakeup-manager/inc/wakeup_audio_manager.h @@ -122,6 +122,8 @@ private: mutex mMutex; bool mVoiceKeyPressed{false}; + + thread mBackgroundVolumeThread; }; } // wakeup diff --git a/plugins/wakeup-manager/inc/wakeup_engine_manager.h b/plugins/wakeup-manager/inc/wakeup_engine_manager.h index 68993cf..4f659ed 100644 --- a/plugins/wakeup-manager/inc/wakeup_engine_manager.h +++ b/plugins/wakeup-manager/inc/wakeup_engine_manager.h @@ -213,6 +213,14 @@ private: wakeup_manager_state_e mWakeupManagerState{WAKEUP_MANAGER_STATE_INACTIVE}; bool mWakeWordAudioRequired{false}; + + typedef struct { + atomic_llong last_audio_fetched{0}; + atomic_llong last_count_fetched{0}; + atomic_llong last_audio_sent{0}; + } StreamingHistory; + + StreamingHistory mStreamingHistory; }; } // wakeup diff --git a/plugins/wakeup-manager/inc/wakeup_manager.h b/plugins/wakeup-manager/inc/wakeup_manager.h index 657c3ec..21f8ccd 100644 --- a/plugins/wakeup-manager/inc/wakeup_manager.h +++ b/plugins/wakeup-manager/inc/wakeup_manager.h @@ -28,6 +28,7 @@ #include <memory> #include <map> +#include <mutex> namespace multiassistant { @@ -241,6 +242,8 @@ private: wakeup_manager_state_e mWakeupManagerState{WAKEUP_MANAGER_STATE_INACTIVE}; mas_wakeup_event_info mLastWakeupEventInfo; + + mutex mMutex; }; } // wakeup diff --git a/plugins/wakeup-manager/src/wakeup_audio_manager.cpp b/plugins/wakeup-manager/src/wakeup_audio_manager.cpp index 78e4eec..81ec9fa 100644 --- a/plugins/wakeup-manager/src/wakeup_audio_manager.cpp +++ b/plugins/wakeup-manager/src/wakeup_audio_manager.cpp @@ -34,6 +34,7 @@ CAudioManager::CAudioManager() CAudioManager::~CAudioManager() { + deinitialize(); } CAudioManager::CAudioManager(IAudioEventObserver *observer) : CAudioManager() @@ -82,6 +83,15 @@ int CAudioManager::deinitialize(void) } mStopStreamingThread.store(false); + if (mBackgroundVolumeThread.joinable()) { + MWR_LOGD("mBackgroundVolumeThread is joinable, trying join()"); + try { + mBackgroundVolumeThread.join(); + } catch (std::exception &e) { + MWR_LOGE("Exception thrown : %s", e.what()); + } + } + sound_manager_remove_focus_state_watch_cb(mSoundFocusWatchId); return 0; @@ -234,7 +244,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time) iter = lead; advance(lead, 1); } - MWR_LOGI("data_count : %zu", mAudioData.size()); + MWR_LOGE("data_count : %zu", mAudioData.size()); lock.unlock(); while (!(mStopStreamingThread.load())) { @@ -315,7 +325,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time) } if (MAS_SPEECH_STREAMING_EVENT_FINISH == speech_data.event) { - MWR_LOGI("[INFO] Finish to get and send speech data"); + MWR_LOGE("[INFO] Finish to get and send speech data"); finish_event_sent = true; break; } @@ -332,7 +342,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time) lock.unlock(); for (const auto& observer : observers) { if (observer) { - MWR_LOGI("No FINISH event sent yet, adding to finalize streaming session"); + MWR_LOGE("No FINISH event sent yet, adding to finalize streaming session"); if (!observer->on_streaming_audio_data( MAS_SPEECH_STREAMING_EVENT_FINISH, final_buffer, sizeof(final_buffer))) { LOGE("[Recorder WARNING] One of the observer returned false"); @@ -341,7 +351,7 @@ void CAudioManager::streaming_audio_data_thread_func(long long start_time) } } mStreamingThreadActive.store(false); - MWR_LOGI("[EXIT]"); + MWR_LOGE("[EXIT]"); } void CAudioManager::add_audio_data(mas_speech_data& data, long long time) @@ -359,7 +369,7 @@ void CAudioManager::add_audio_data(mas_speech_data& data, long long time) static auto last = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now(); if (now - last > interval) { - MWR_LOGI("Feeding audio data : num(%d), now(%" PRId64 "), %d %zu", + MWR_LOGE("Feeding audio data : num(%d), now(%" PRId64 "), %d %zu", num, now.time_since_epoch().count(), mStreamingThreadActive.load(), mAudioData.size()); last = now; @@ -518,10 +528,19 @@ void CAudioManager::stop_streaming_follow_up_data() mStopStreamingThread.store(false); } -void CAudioManager::set_background_volume(double ratio) +static void set_background_volume_thread_func(double ratio) { + MWR_LOGI("[ENTER]"); dependency_resolver_set_background_volume(ratio); } +void CAudioManager::set_background_volume(double ratio) +{ + if (mBackgroundVolumeThread.joinable()) { + mBackgroundVolumeThread.join(); + } + mBackgroundVolumeThread = thread(&set_background_volume_thread_func, ratio); +} + } // wakeup } // multiassistant diff --git a/plugins/wakeup-manager/src/wakeup_engine_manager.cpp b/plugins/wakeup-manager/src/wakeup_engine_manager.cpp index 9a5b154..307ff3c 100644 --- a/plugins/wakeup-manager/src/wakeup_engine_manager.cpp +++ b/plugins/wakeup-manager/src/wakeup_engine_manager.cpp @@ -36,6 +36,16 @@ static auto contains(const C& v, const T& x) -> decltype(end(v), true) return end(v) != find(begin(v), end(v), x); } +static long long get_current_milliseconds_after_epoch() +{ + 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(); + + return value.count(); +} + CWakeupEngineManager::CWakeupEngineManager() { } @@ -215,7 +225,7 @@ bool CWakeupEngineManager::set_assistant_language(string appid, string language) void CWakeupEngineManager::set_assistant_activated(string appid, bool activated) { - MWR_LOGI("[ENTER] : %s %d", appid.c_str(), activated); + MWR_LOGE("[ENTER] : %s %d", appid.c_str(), activated); for (auto& info : mEngineInfo) { const auto& iter = find_if(info.assistant_list.begin(), info.assistant_list.end(), [appid](const string& assistant) { @@ -275,7 +285,7 @@ void CWakeupEngineManager::set_wake_word_audio_require_flag(bool require) void CWakeupEngineManager::streaming_speech_data_thread_func() { - MWR_LOGI("[ENTER]"); + MWR_LOGE("[ENTER]"); if (nullptr == mSelectedEngine) { MWR_LOGE("No Engine Selected"); @@ -380,6 +390,8 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() /* get feedback data */ if (interface && interface->get_utterance_data) { ret = interface->get_utterance_data(index, &speech_data); + mStreamingHistory.last_audio_fetched.store(get_current_milliseconds_after_epoch()); + if (0 != ret) { /* empty queue */ MWR_LOGD("[DEBUG] No feedback data. Waiting mode : %d", ret); @@ -392,6 +404,7 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() MWR_LOGD("[INFO] Resume thread"); break; } + mStreamingHistory.last_count_fetched.store(get_current_milliseconds_after_epoch()); if (g_speech_pcm_wait_count < cnt) { unsigned char final_buffer[2] = {'\0', }; MWR_LOGE("[ERROR] Wrong request, there's no pcm data"); @@ -413,6 +426,7 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() MAS_SPEECH_STREAMING_EVENT_FINISH, final_buffer, sizeof(final_buffer))) { LOGE("[Recorder WARNING] One of the observer returned false"); } + mStreamingHistory.last_audio_sent.store(get_current_milliseconds_after_epoch()); } } return; @@ -443,8 +457,8 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() const int max_burst_count = 3; if (++burst_count >= max_burst_count) { burst_count = 0; - this_thread::sleep_for(chrono::milliseconds(sleep_duration_in_millis)); MWR_LOGI("[INFO] Streaming data burst transmission detected, forcing sleep"); + this_thread::sleep_for(chrono::milliseconds(sleep_duration_in_millis)); } for (const auto& observer : mObservers) { if (observer) { @@ -452,11 +466,12 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() speech_data.event, speech_data.buffer, speech_data.len)) { LOGE("[Recorder WARNING] One of the observer returned false"); } + mStreamingHistory.last_audio_sent.store(get_current_milliseconds_after_epoch()); } } if (MAS_SPEECH_STREAMING_EVENT_FINISH == speech_data.event) { - MWR_LOGI("[INFO] Finish to get and send speech data"); + MWR_LOGE("[INFO] Finish to get and send speech data"); finish_event_sent = true; break; } @@ -464,16 +479,18 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() index++; } } + MWR_LOGE("[INFO] Streaming loop exit"); if (true != finish_event_sent) { unsigned char final_buffer[2] = {'\0', }; for (const auto& observer : mObservers) { if (observer) { - MWR_LOGI("No FINISH event sent yet, adding to finalize streaming session"); + MWR_LOGE("No FINISH event sent yet, adding to finalize streaming session"); if (!observer->on_streaming_audio_data( MAS_SPEECH_STREAMING_EVENT_FINISH, final_buffer, sizeof(final_buffer))) { LOGE("[Recorder WARNING] One of the observer returned false"); } + mStreamingHistory.last_audio_sent.store(get_current_milliseconds_after_epoch()); } } #ifdef BUF_SAVE_MODE @@ -486,7 +503,7 @@ void CWakeupEngineManager::streaming_speech_data_thread_func() #endif } - MWR_LOGI("[EXIT]"); + MWR_LOGE("[EXIT]"); } void CWakeupEngineManager::start_streaming_current_utterance_data() @@ -503,7 +520,11 @@ void CWakeupEngineManager::stop_streaming_current_utterance_data() { MWR_LOGI("[ENTER]"); if (mStreamingThread.joinable()) { - MWR_LOGD("mStreamingThread is joinable, trying join()"); + MWR_LOGE("mStreamingThread is joinable, trying join() %lld %lld %lld %lld", + get_current_milliseconds_after_epoch(), + mStreamingHistory.last_audio_fetched.load(), + mStreamingHistory.last_count_fetched.load(), + mStreamingHistory.last_audio_sent.load()); mStopStreamingThread.store(true); mStreamingThread.join(); } diff --git a/plugins/wakeup-manager/src/wakeup_manager.cpp b/plugins/wakeup-manager/src/wakeup_manager.cpp index 7f856ea..31eb2b9 100644 --- a/plugins/wakeup-manager/src/wakeup_manager.cpp +++ b/plugins/wakeup-manager/src/wakeup_manager.cpp @@ -21,6 +21,9 @@ #include "dependency_resolver.h" #include <algorithm> + +#include <boost/optional.hpp> + namespace multiassistant { namespace wakeup @@ -100,7 +103,7 @@ void CWakeupManager::initialize_wakeup_policy() bool CWakeupManager::initialize() { - MWR_LOGI("[ENTER]"); + MWR_LOGE("[ENTER]"); mPolicyEventObserver.set_wakeup_manager(this); mEngineEventObserver.set_wakeup_manager(this); @@ -135,7 +138,7 @@ bool CWakeupManager::initialize() bool CWakeupManager::deinitialize() { - MWR_LOGI("[ENTER]"); + MWR_LOGE("[ENTER]"); stop_streaming_duration_timer(); @@ -152,7 +155,7 @@ bool CWakeupManager::deinitialize() mWakeupSettings.deinitialize(); mAssistantLanguageInfo.clear(); - MWR_LOGI("[END]"); + MWR_LOGE("[END]"); return true; } @@ -307,7 +310,7 @@ bool CWakeupManager::set_assistant_enabled(string appid, bool enabled) bool CWakeupManager::set_default_assistant(string appid) { - MWR_LOGI("[ENTER]"); + MWR_LOGE("[ENTER] %s", appid.c_str()); /* Check if previous default assistant has to be deactivated */ bool activated = true; @@ -398,6 +401,7 @@ STREAMING_MODE CWakeupManager::get_streaming_mode() bool CWakeupManager::set_streaming_mode(STREAMING_MODE mode) { + lock_guard<mutex> lock(mMutex); mStreamingMode = mode; return true; } @@ -511,29 +515,30 @@ bool CWakeupManager::change_voice_key_status(ma_voice_key_status_e status) { bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len) { - MWR_LOGI("[ENTER] : %d", event); + MWR_LOGE("[ENTER] : %d", event); if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState) return false; bool start_recording = false; bool stop_recording = false; + boost::optional<ma_voice_key_status_e> next_voice_key_status; if (MAS_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) { if (VOICE_KEY_SUPPORT_MODE_NONE != mCurrentVoiceKeySupportMode) { start_recording = true; } - change_voice_key_status(MA_VOICE_KEY_STATUS_PRESSED); + next_voice_key_status = MA_VOICE_KEY_STATUS_PRESSED; } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) { if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode || VOICE_KEY_SUPPORT_MODE_ALL == mCurrentVoiceKeySupportMode) { stop_recording = true; } - change_voice_key_status(MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH); + next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH; } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) { if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode) { stop_recording = true; } - change_voice_key_status(MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP); + next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP; } if (start_recording) { @@ -586,6 +591,10 @@ bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, } } + if (next_voice_key_status) { + change_voice_key_status(*next_voice_key_status); + } + MWR_LOGD("[END]"); return true; } @@ -674,6 +683,7 @@ bool CWakeupManager::start_streaming_utterance_data() bool CWakeupManager::stop_streaming_utterance_data() { MWR_LOGI("[ENTER]"); + if (STREAMING_MODE::UTTERANCE != mStreamingMode) return false; mAudioManager.stop_streaming_current_utterance_data(); diff --git a/src/service_config.cpp b/src/service_config.cpp index d797480..efd5682 100644 --- a/src/service_config.cpp +++ b/src/service_config.cpp @@ -79,7 +79,7 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba key = xmlNodeGetContent(child_node); if (key) { temp.supported_lang[temp.cnt_lang++] = strdup((const char*)key); - MAS_LOGD("Language : %s", key); + MAS_LOGI("Language : %s", key); xmlFree(key); } } @@ -93,13 +93,13 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba key = xmlNodeGetContent(child_node); if (key) { temp.wakeup_list[temp.cnt_wakeup] = strdup((const char*)key); - MAS_LOGD("Wakeup Word : %s", key); + MAS_LOGI("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); + MAS_LOGI("Wakeup Language for %s : %s", temp.wakeup_list[temp.cnt_wakeup], prop); xmlFree(prop); } temp.cnt_wakeup++; @@ -111,21 +111,21 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba key = xmlNodeGetContent(cur); if (key) { temp.name = strdup((const char*)key); - MAS_LOGD("Name : %s", key); + MAS_LOGI("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); + MAS_LOGI("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); + MAS_LOGI("Icon Path : %s", key); xmlFree(key); } /* For supporting previous version of schema - START */ @@ -134,7 +134,7 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba key = xmlNodeGetContent(cur); if (key) { temp.wakeup_engine[0] = strdup((const char*)key); - MAS_LOGD("Wakeup Engine : %s", key); + MAS_LOGI("Wakeup Engine : %s", key); xmlFree(key); } temp.cnt_wakeup_engine = 1; @@ -149,7 +149,7 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba key = xmlNodeGetContent(child_node); if (key) { temp.wakeup_engine[temp.cnt_wakeup_engine] = strdup((const char*)key); - MAS_LOGD("Wakeup Engine : %s", key); + MAS_LOGI("Wakeup Engine : %s", key); xmlFree(key); } temp.cnt_wakeup_engine++; @@ -167,7 +167,7 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba if (0 == xmlStrcasecmp(key, reinterpret_cast<const xmlChar*>("true"))) { temp.custom_ui_option = true; } - MAS_LOGD("Use custom UI : %d", temp.custom_ui_option); + MAS_LOGI("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)) { @@ -182,14 +182,14 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba } else { temp.voice_key_support_mode = VOICE_KEY_SUPPORT_MODE_NONE; } - MAS_LOGD("Voice key support mode : %s", cur->name); + MAS_LOGI("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); + MAS_LOGI("Voice key tap duration : %s", key); xmlFree(key); } } else if (cur->name && 0 == xmlStrcmp(cur->name, (const xmlChar*)MA_TAG_ASSISTANT_AUDIO_DATA_PROCESSOR)) { @@ -239,6 +239,7 @@ int CServiceConfig::parse_assistant_info(service_config_assistant_info_cb callba int CServiceConfig::get_assistant_info(service_config_assistant_info_cb callback, void* user_data) { + MAS_LOGI("[ENTER] %s", MA_ASSISTANT_INFO); const char *suffix = ".xml"; DIR *d; @@ -249,9 +250,10 @@ int CServiceConfig::get_assistant_info(service_config_assistant_info_cb callback 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); + const size_t path_max = _POSIX_PATH_MAX * 2; + char fullpath[path_max]; + snprintf(fullpath, path_max - 1, "%s/%s", MA_ASSISTANT_INFO, dir->d_name); + MAS_LOGI("Parsing file : %s\n", fullpath); parse_assistant_info(callback, fullpath, user_data); } } @@ -259,6 +261,7 @@ int CServiceConfig::get_assistant_info(service_config_assistant_info_cb callback closedir(d); } + MAS_LOGI("[EXIT]"); return 0; } diff --git a/src/service_ipc_dbus.cpp b/src/service_ipc_dbus.cpp index 9e7acd0..d9038a5 100644 --- a/src/service_ipc_dbus.cpp +++ b/src/service_ipc_dbus.cpp @@ -20,11 +20,14 @@ #include <message_port.h> #include <chrono> +#include <atomic> #include "service_common.h" #include "service_main.h" #include "service_ipc_dbus.h" +std::atomic_size_t gAudioDataMileage{0}; + int CServiceIpcDbus::reconnect() { if (!mConnectionSender || !mConnectionListener) { @@ -267,15 +270,17 @@ int CServiceIpcDbus::send_streaming_audio_data(pid_t pid, int event, void* data, MAS_LOGE("Buffer overflow : %zu %zu", new_size, total_size); return -1; } + gAudioDataMileage.fetch_add(data_size); const long long minimum_flush_interval = 20; static long long last_flush_time = get_current_milliseconds_after_epoch(); long long current_time = get_current_milliseconds_after_epoch(); static int last_serial_waiting_for_flush = -1; - if (0 == header.streaming_data_serial % 50) { + if (0 == header.streaming_data_serial % 50 || MAS_SPEECH_STREAMING_EVENT_CONTINUE != event) { last_serial_waiting_for_flush = header.streaming_data_serial; - MAS_LOGI("queueing streaming data, serial : %d", last_serial_waiting_for_flush); + MAS_LOGE("queueing streaming data, serial : %d %d %zu", + last_serial_waiting_for_flush, event, gAudioDataMileage.load()); } if (pending_buffer_size + total_size > STREAMING_BUFFER_SIZE || MAS_SPEECH_STREAMING_EVENT_FINISH == event || @@ -304,13 +309,14 @@ int CServiceIpcDbus::send_streaming_audio_data(pid_t pid, int event, void* data, } if (-1 != last_serial_waiting_for_flush) { - MAS_LOGI("flushing streaming data, serial : %d", last_serial_waiting_for_flush); + MAS_LOGE("flushing streaming data, serial : %d %zu", + last_serial_waiting_for_flush, gAudioDataMileage.load()); last_serial_waiting_for_flush = -1; } } if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) { - MAS_LOGE("Sending FINISH event"); + MAS_LOGE("Sending FINISH event : %zu", gAudioDataMileage.load()); bundle *b = bundle_create(); if (b) { bundle_add_byte(b, "content", buffer, total_size); @@ -1072,23 +1078,40 @@ int CServiceIpcDbus::masc_ui_dbus_enable_common_ui(int enable) return 0; } +static void print_duration(int num_messages, std::chrono::time_point<std::chrono::steady_clock> started) +{ + const std::chrono::milliseconds threshold(100); + auto finished = std::chrono::steady_clock::now(); + auto interval = finished - started; + if (interval > threshold) { + MAS_LOGE("DBus messages processed : %d, %lld", num_messages, + std::chrono::duration_cast<std::chrono::milliseconds>(interval).count()); + } +} + static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler) { + int num_messages = 0; + auto started = std::chrono::steady_clock::now(); + CServiceIpcDbus* service_ipc = static_cast<CServiceIpcDbus*>(data); if (NULL == service_ipc) { MAS_LOGE("Error : service_ipc NULL"); + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } DBusConnection* mConnectionListener = service_ipc->get_connection_listener(); if (NULL == mConnectionListener) { MAS_LOGE("Error : mConnectionListener NULL"); + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } CServiceIpcDbusDispatcher* dispatcher = service_ipc->get_dispatcher(); if (NULL == dispatcher) { MAS_LOGE("Error : dispatcher NULL"); + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } @@ -1100,11 +1123,13 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle if (TRUE != dbus_connection_get_is_connected(mConnectionListener)) { MAS_LOGE("[ERROR] Connection is disconnected"); + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } /* loop again if we haven't read a message */ if (NULL == msg) { + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } @@ -1134,6 +1159,8 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle 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)) { + /* Reset mileage data for logging */ + gAudioDataMileage.store(0); 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)) { @@ -1176,13 +1203,16 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle dispatcher->on_ui_change_assistant(mConnectionListener, msg); } else { - MAS_LOGD("Message is NOT valid"); + MAS_LOGE("Message is NOT valid"); /* Invalid method */ } /* free the message */ dbus_message_unref(msg); + + num_messages++; } + print_duration(num_messages, started); return ECORE_CALLBACK_RENEW; } diff --git a/src/service_main.cpp b/src/service_main.cpp index ac25d36..e3482e6 100644 --- a/src/service_main.cpp +++ b/src/service_main.cpp @@ -27,6 +27,12 @@ #include <string.h> #include <glib.h> +#include <chrono> +#include <ctime> +#include <list> +#include <sstream> +#include <tuple> + #include "service_common.h" #include "service_main.h" #include "service_plugin.h" @@ -219,7 +225,7 @@ int CServiceMain::client_send_result(pid_t pid, const char* display_text, int CServiceMain::client_send_recognition_result(pid_t pid, int result) { - MAS_LOGI("[Enter] pid(%d), result(%d)", pid, result); + MAS_LOGE("[Enter] pid(%d), result(%d)", pid, result); if (!is_current_assistant(pid)) return -1; bool ui_panel_enabled = mServicePlugin.is_ui_panel_enabled(); @@ -243,7 +249,7 @@ int CServiceMain::client_send_recognition_result(pid_t pid, int result) int CServiceMain::client_start_streaming_audio_data(pid_t pid, int type) { - MAS_LOGI("[ENTER] %d", type); + MAS_LOGE("[ENTER] %d", type); int ret = -1; if (!is_current_assistant(pid)) { @@ -270,7 +276,7 @@ int CServiceMain::client_start_streaming_audio_data(pid_t pid, int type) int CServiceMain::client_stop_streaming_audio_data(pid_t pid, int type) { - MAS_LOGI("[ENTER] %d", type); + MAS_LOGE("[ENTER] %d", type); int ret = -1; if (!is_current_assistant(pid)) { @@ -316,13 +322,50 @@ int CServiceMain::client_set_assistant_specific_command(pid_t pid, const char *c int CServiceMain::client_set_background_volume(pid_t pid, double ratio) { - if (!is_current_assistant(pid)) return -1; + bool valid = is_current_assistant(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; } + + /* Better extracting this into a new Ducking Management class */ + const int max_history_size = 5; + static std::list<std::tuple<pid_t, std::string, double, std::time_t, bool>> history; + history.push_front(std::make_tuple(pid, pid_appid, ratio, + std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()), valid)); + if (history.size() > max_history_size) history.pop_back(); + + std::stringstream ss; + for (auto item : history) { + std::time_t time_info = std::get<3>(item); + char time_string[32]; + struct tm tm; + localtime_r(&time_info, &tm); + std::strftime(time_string, sizeof(time_string), "%H%M%S", &tm); + ss << "["; + ss << std::get<0>(item); + ss << ","; + ss << std::get<1>(item); + ss << ","; + ss << std::get<2>(item); + ss << ","; + ss << time_string; + ss << ","; + ss << std::get<4>(item); + ss << "]"; + } + MAS_LOGW("History : %s", ss.str().c_str()); + + if (!valid) return -1; + + if (ratio < 1.0f) { + mLastDuckingRequester = pid; + } else { + mLastDuckingRequester = -1; + } + mServicePlugin.set_background_volume(pid_appid.c_str(), ratio); return 0; } @@ -638,7 +681,7 @@ static void active_state_changed_cb(std::string key, void* user_data) boost::optional<bool> activated = manager->get_bool(MULTI_ASSISTANT_SETTINGS_ACTIVATED); if (activated) { - MAS_LOGI("multi-assistant active state : %d\n", *activated); + MAS_LOGE("multi-assistant active state : %d\n", *activated); CServicePlugin *plugin = nullptr; if (g_service_main) { @@ -914,7 +957,7 @@ int CServiceMain::set_current_client_by_wakeup_word(const char *wakeup_word) if (0 < strlen(items[loop].wakeup_word[inner_loop])) { if (0 == strncmp(wakeup_word, items[loop].wakeup_word[inner_loop], MAX_WAKEUP_WORD_LEN)) { mCurrentClientInfo = loop; - MAS_LOGI("mCurrentClientInfo : %d %s", mCurrentClientInfo, wakeup_word); + MAS_LOGE("mCurrentClientInfo : %d %s", mCurrentClientInfo, wakeup_word); ret = 0; } } @@ -937,7 +980,7 @@ int CServiceMain::set_current_client_by_wakeup_word(const char *wakeup_word) } if (0 == strncmp(wakeup_word, comparand, MAX_WAKEUP_WORD_LEN)) { mCurrentClientInfo = loop; - MAS_LOGI("mCurrentClientInfo : %d %s", mCurrentClientInfo, wakeup_word); + MAS_LOGE("mCurrentClientInfo : %d %s", mCurrentClientInfo, wakeup_word); ret = 0; } } @@ -950,6 +993,11 @@ int CServiceMain::set_current_client_by_wakeup_word(const char *wakeup_word) if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) { pid_t pid = get_client_pid_by_appid(items[prev_selection].appid); mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_INACTIVE); + if (mLastDuckingRequester == pid) { + MAS_LOGE("Last ducking requester is deactivated, resetting background volume"); + mServicePlugin.set_background_volume(items[prev_selection].appid, 1.0f); + mLastDuckingRequester = -1; + } } } @@ -967,7 +1015,7 @@ int CServiceMain::set_current_client_by_appid(const char *appid) 0 < strlen(items[loop].appid) && 0 < strlen(items[loop].wakeup_word[0])) { if (strncmp(appid, items[loop].appid, MAX_APPID_LEN) == 0) { - MAS_LOGI("mCurrentClientInfo : %d %s", mCurrentClientInfo, appid); + MAS_LOGE("mCurrentClientInfo : %d %s", mCurrentClientInfo, appid); mCurrentClientInfo = loop; ret = 0; } @@ -978,6 +1026,11 @@ int CServiceMain::set_current_client_by_appid(const char *appid) if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) { pid_t pid = get_client_pid_by_appid(items[prev_selection].appid); mServiceIpc.change_active_state(pid, MA_ACTIVE_STATE_INACTIVE); + if (mLastDuckingRequester == pid) { + MAS_LOGE("Last ducking requester is deactivated, resetting background volume"); + mServicePlugin.set_background_volume(items[prev_selection].appid, 1.0f); + mLastDuckingRequester = -1; + } } } @@ -1262,7 +1315,7 @@ bool CServiceMain::is_valid_wakeup_engine(const char* appid) bool CServiceMain::app_create(void *data) { // Todo: add your code here. - MAS_LOGI("[ENTER] Service app create"); + MAS_LOGE("[ENTER] Service app create"); g_service_main = this; @@ -1275,9 +1328,22 @@ bool CServiceMain::app_create(void *data) 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"); + const int retry_interval = 5; + const int max_retry_count = 5; + int retry_count = 0; + int ret; + do { + ret = mServiceIpc.open_connection(); + if (0 != ret) { + sleep(retry_interval); + MAS_LOGE("[ERROR] Fail to open connection, Retrying : %d", retry_count); + } + } while (0 != ret && retry_count++ < max_retry_count); + + if (retry_count >= max_retry_count) { + MAS_LOGE("[ERROR] Maximum retry count reached, restarting..."); + service_app_exit(); + return false; } initialize_service_plugin(); @@ -1297,13 +1363,13 @@ bool CServiceMain::app_create(void *data) mPackageUpdateMonitor.initialize(); - MAS_LOGI("[END] Service app create"); + MAS_LOGE("[END] Service app create"); return true; } void CServiceMain::app_terminate(void *data) { - MAS_LOGI("[ENTER]"); + MAS_LOGE("[ENTER]"); mPackageUpdateMonitor.deinitialize(); @@ -1319,7 +1385,7 @@ void CServiceMain::app_terminate(void *data) g_service_main = nullptr; - MAS_LOGI("[END]"); + MAS_LOGE("[END]"); return; } @@ -1375,7 +1441,15 @@ int CServiceMain::on_initialize(pid_t pid) { int CServiceMain::on_deinitialize(pid_t pid) { MAS_LOGD("[Enter] pid(%d)", pid); + if (mLastDuckingRequester == pid) { + MAS_LOGE("Last ducking requester has disconnected, resetting background volume"); + std::string pid_appid = mClientManager.find_client_appid_by_pid( pid); + mServicePlugin.set_background_volume(pid_appid.c_str(), 1.0f); + mLastDuckingRequester = -1; + } + mClientManager.destroy_client_by_pid(pid); + return 0; } |