Add new class for managing state of server 44/279844/2
authorSuyeon Hwang <stom.hwang@samsung.com>
Wed, 10 Aug 2022 12:11:22 +0000 (21:11 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Fri, 19 Aug 2022 07:07:01 +0000 (16:07 +0900)
- Requirement:
The TTS engine library needs to manage its state.

- Solution:
This patch adds new class StateManager which helps to manage state of
TTS service. Through this new class, the TTS engine library can easily
change the state and notify it.

Change-Id: I3fe6a38fcd9f55f8027b8ed1cdec8ca453cbe9a8
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/CMakeLists.txt
server/StateManager.h [new file with mode: 0644]
server/ttsd_main.h
server/ttsd_player.cpp
server/ttsd_server.c
server/ttsd_state.cpp [new file with mode: 0644]
server/ttsd_state.h [new file with mode: 0644]

index 706021a371aba8a22ac166f2559ed96ac0d478f5..144da806cde808308b0e65526f54caca2f1a73e8 100644 (file)
@@ -14,6 +14,7 @@ SET(SRCS
        PlayerThread.cpp
        ActivatedModes.cpp
        ttsd_server.c
+       ttsd_state.cpp
        ../common/tts_config_mgr.c
        ../common/tts_config_parser.c
 )
diff --git a/server/StateManager.h b/server/StateManager.h
new file mode 100644 (file)
index 0000000..eb8ddf2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+*  Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*  http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+
+
+
+#ifndef __TTSD_STATE_MANAGER_H_
+#define __TTSD_STATE_MANAGER_H_
+
+
+#include <mutex>
+
+#include "ttsd_state.h"
+
+
+class StateManager {
+public:
+       StateManager(ttsd_state_changed_cb callback);
+       ~StateManager();
+
+       ttsd_state_e getState();
+       void setState(ttsd_state_e state);
+
+private:
+       static void notifyStateChangeOnMainThread(void* data);
+
+private:
+       ttsd_state_e __beforeState;
+       ttsd_state_e __currentState;
+       std::mutex __stateMutex;
+
+       ttsd_state_changed_cb __callback;
+};
+
+#endif /* __TTSD_STATE_MANAGER_H_ */
index d35def8a9226f62c8ec76813034f6e0e16d4ae75..40e886c3e31599d392eb154e69b5c1b78b3ccf41 100644 (file)
@@ -65,6 +65,13 @@ typedef enum {
        TTSD_INTERRUPTED_STOPPED        /**< Current state change 'Ready' */
 } ttsd_interrupted_code_e;
 
+typedef enum {
+       TTSD_STATE_INVALID = -1,
+       TTSD_STATE_READY = 0, /**< 'Idle' state */
+       TTSD_STATE_SYNTHESIZING = 1, /**< 'Synthesizing' state */
+       TTSD_STATE_PLAYING = 2 /**< 'Playing' state */
+} ttsd_state_e;
+
 typedef struct {
        char* engine_id;
        char* engine_name;
index e2aa2e22aaec0fa21ba6cbc760a954ef9be5071a..a2198d4e2ab80d8823ee7545f44f319d961058f6 100644 (file)
@@ -15,6 +15,7 @@
 #include "ttsd_data.h"
 #include "ttsd_ipc.h"
 #include "ttsd_player.h"
+#include "ttsd_state.h"
 
 #include "BackgroundVolume.h"
 #include "AudioStream.h"
@@ -59,6 +60,16 @@ static void __set_playing_status(bool is_playing)
 {
        int ret = vconf_set_bool(TTS_PLAYING_STATUS_KEY, is_playing ? 1 : 0);
        SLOG(LOG_INFO, tts_tag(), "[Player] Set playing status (%s). ret(%d)", is_playing ? "True" : "False", ret);
+
+       if (is_playing) {
+               ttsd_state_set_state(TTSD_STATE_PLAYING);
+       } else {
+               if (ttsd_data_get_synth_control() == TTSD_SYNTHESIS_CONTROL_DOING) {
+                       ttsd_state_set_state(TTSD_STATE_SYNTHESIZING);
+               } else {
+                       ttsd_state_set_state(TTSD_STATE_READY);
+               }
+       }
 }
 
 #ifdef BUF_SAVE_MODE
index f515c33e7dd5e46ad702709da7d3f7724fd3c50c..488787561b5fbe6ace2a22d059a498b9267a15a0 100644 (file)
@@ -22,6 +22,7 @@
 #include "ttsd_engine_agent.h"
 #include "ttsd_main.h"
 #include "ttsd_player.h"
+#include "ttsd_state.h"
 #include "ttsd_server.h"
 
 
@@ -159,6 +160,10 @@ static void __synthesis(unsigned int uid)
                g_wait_timer = ecore_timer_add(0.05, __wait_synthesis, (void*)credential);
        }
 
+       if (ttsd_data_get_synth_control() == TTSD_SYNTHESIS_CONTROL_DOING && ttsd_state_get_state() == TTSD_STATE_READY) {
+               ttsd_state_set_state(TTSD_STATE_SYNTHESIZING);
+       }
+
        free(credential);
        credential = NULL;
        ttsd_data_destroy_speak_data(speak_data);
@@ -556,6 +561,10 @@ int ttsd_initialize(ttse_request_callback_s *callback)
                SLOG(LOG_ERROR, tts_tag(), "[Server WARNING] Fail to initialize config.");
        }
 
+       if (TTSD_ERROR_NONE != ttsd_state_initialize(NULL)) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server WARNING] Fail to initialize state.");
+       }
+
        /* player init */
        if (ttsd_player_init()) {
                SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to initialize player init.");
@@ -625,6 +634,7 @@ int ttsd_finalize()
        }
 
        ttsd_config_finalize();
+       ttsd_state_finalize();
 
        int ret = TTSD_ERROR_NONE;
        ret = ttsd_player_release();
diff --git a/server/ttsd_state.cpp b/server/ttsd_state.cpp
new file mode 100644 (file)
index 0000000..14e9f4c
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+*  Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*  http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+
+
+#include <Ecore.h>
+
+#include "StateManager.h"
+#include "ttsd_state.h"
+
+
+using namespace std;
+
+
+static StateManager* g_stateManager = nullptr;
+
+StateManager::StateManager(ttsd_state_changed_cb callback) :
+       __beforeState(TTSD_STATE_READY), __currentState(TTSD_STATE_READY), __callback(callback)
+{
+       SLOG(LOG_INFO, tts_tag(), "[StateManager] Constructor");
+}
+
+StateManager::~StateManager()
+{
+       SLOG(LOG_INFO, tts_tag(), "[StateManager] Destructor");
+       __beforeState = TTSD_STATE_READY;
+       __currentState = TTSD_STATE_READY;
+       __callback = nullptr;
+}
+
+ttsd_state_e StateManager::getState()
+{
+       lock_guard<mutex> lock(__stateMutex);
+       return __currentState;
+}
+
+void StateManager::setState(ttsd_state_e state)
+{
+       unique_lock<mutex> lock(__stateMutex);
+       __beforeState = __currentState;
+       __currentState = state;
+
+       if (__beforeState == __currentState) {
+               return;
+       }
+
+       SLOG(LOG_INFO, tts_tag(), "[StateManager] StateManager is changed. (%d) -> (%d)", __beforeState, __currentState);
+       lock.unlock();
+       ecore_main_loop_thread_safe_call_async(notifyStateChangeOnMainThread, static_cast<void*>(this));
+}
+
+void StateManager::notifyStateChangeOnMainThread(void* data)
+{
+       if (nullptr == data) {
+               SLOG(LOG_ERROR, tts_tag(), "[StateManager] Invalid data is passed");
+               return;
+       }
+
+       StateManager* stateManager = static_cast<StateManager*>(data);
+
+       unique_lock<mutex> lock(stateManager->__stateMutex);
+       ttsd_state_e before = stateManager->__beforeState;
+       ttsd_state_e current = stateManager->__currentState;
+       lock.unlock();
+
+       if (stateManager->__callback) {
+               stateManager->__callback(before, current);
+       }
+}
+
+
+int ttsd_state_initialize(ttsd_state_changed_cb callback)
+{
+       g_stateManager = new(nothrow) StateManager(callback);
+
+       if (nullptr == g_stateManager) {
+               SLOG(LOG_ERROR, tts_tag(), "[StateManager] Fail to initialize StateManager");
+               return TTSD_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TTSD_ERROR_NONE;
+}
+
+int ttsd_state_finalize()
+{
+       if (nullptr == g_stateManager) {
+               SLOG(LOG_ERROR, tts_tag(), "[StateManager] StateManager is not initialized");
+               return TTSD_ERROR_INVALID_STATE;
+       }
+
+       delete g_stateManager;
+       g_stateManager = nullptr;
+
+       return TTSD_ERROR_NONE;
+}
+
+int ttsd_state_set_state(ttsd_state_e state)
+{
+       if (nullptr == g_stateManager) {
+               SLOG(LOG_ERROR, tts_tag(), "[StateManager] StateManager is not initialized");
+               return TTSD_ERROR_INVALID_STATE;
+       }
+
+       g_stateManager->setState(state);
+       return TTSD_ERROR_NONE;
+}
+
+ttsd_state_e ttsd_state_get_state()
+{
+       if (nullptr == g_stateManager) {
+               SLOG(LOG_ERROR, tts_tag(), "[StateManager] StateManager is not initialized");
+               return TTSD_STATE_INVALID;
+       }
+
+       return g_stateManager->getState();
+}
diff --git a/server/ttsd_state.h b/server/ttsd_state.h
new file mode 100644 (file)
index 0000000..b03506d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+*  Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*  http://www.apache.org/licenses/LICENSE-2.0
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+
+
+#ifndef __TTSD_STATE_H__
+#define __TTSD_STATE_H__
+
+#include "ttsd_main.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef void (*ttsd_state_changed_cb)(ttsd_state_e before, ttsd_state_e current);
+
+
+int ttsd_state_initialize(ttsd_state_changed_cb callback);
+
+int ttsd_state_finalize();
+
+int ttsd_state_set_state(ttsd_state_e state);
+
+ttsd_state_e ttsd_state_get_state();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TTSD_STATE_H__ */