--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 <app_manager_extension.h>
+#include <tzplatform_config.h>
+#include <system_info.h>
+#include <vconf.h>
+#include <gtest/gtest.h>
+#include <Ecore.h>
+
+#include "test_util.h"
+
+
+TtsTestUtility::TtsTestUtility()
+{
+ mHandle = nullptr;
+ mCurrentState = TTS_STATE_CREATED;
+ mCurrentServiceState = TTS_SERVICE_STATE_NONE;
+
+ mLanguage = nullptr;
+ mVoiceType = TTS_VOICE_TYPE_AUTO;
+ mScreenReaderOn = false;
+ mUtteranceStarted = false;
+ mUtteranceCompleted = false;
+ mErrorOccured = false;
+ mUttId = -1;
+
+ mPCMData = nullptr;
+ mPCMSize = 0;
+
+ CreateHandle();
+}
+
+TtsTestUtility::~TtsTestUtility()
+{
+ DestroyHandle();
+
+ free(mLanguage);
+ mLanguage = nullptr;
+
+ free(mPCMData);
+ mPCMData = nullptr;
+ mPCMSize = 0;
+}
+
+void TtsTestUtility::StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mCurrentState = current;
+}
+
+void TtsTestUtility::ServiceStateChangedCallback(tts_h tts, tts_service_state_e previous, tts_service_state_e current, void* user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mCurrentServiceState = current;
+}
+
+void TtsTestUtility::ScreenReaderChangedCallback(tts_h tts, bool is_on, void* user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mScreenReaderOn = is_on;
+}
+
+void TtsTestUtility::UtteranceStartedCallback(tts_h tts, int utt_id, void* user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mUtteranceStarted = true;
+}
+
+void TtsTestUtility::UtteranceCompletedCallback(tts_h tts, int utt_id, void *user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mUtteranceCompleted = true;
+ instance->mUttId = utt_id;
+}
+
+void TtsTestUtility::ErrorCallback(tts_h tts, int utt_id, tts_error_e reason, void* user_data)
+{
+ auto instance = reinterpret_cast<TtsTestUtility *>(user_data);
+ instance->mErrorOccured = true;
+}
+
+void TtsTestUtility::TerminateCurrentEngine()
+{
+ char* engineId = vconf_get_str(VCONFKEY_TTS_ENGINE_DEFAULT);
+
+ app_context_h context = nullptr;
+ app_manager_get_app_context(engineId, &context);
+ free(engineId);
+
+ ASSERT_NE(context, nullptr);
+
+ EXPECT_EQ(app_manager_terminate_app(context), APP_MANAGER_ERROR_NONE);
+ EXPECT_EQ(app_context_destroy(context), APP_MANAGER_ERROR_NONE);
+}
+
+void TtsTestUtility::WaitUntilEngineTerminated(int duration)
+{
+ auto engineChcker = [](void) {
+ bool is_running = false;
+
+ char* engineId = vconf_get_str(VCONFKEY_TTS_ENGINE_DEFAULT);
+ app_manager_is_running(engineId, &is_running);
+ free(engineId);
+
+ return !is_running;
+ };
+
+ WaitCondtion(engineChcker, duration);
+}
+
+bool TtsTestUtility::IsFeatureSupported()
+{
+ bool isSupported = false;
+ system_info_get_platform_bool("http://tizen.org/feature/speech.synthesis", &isSupported);
+ return isSupported;
+}
+
+void TtsTestUtility::GetTestPCMData()
+{
+ static const char* PCM_PATH = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.tts-unittests/res/test_pcm.dat");
+
+ FILE* fp_in = fopen(PCM_PATH, "rb");
+ if (fp_in == nullptr) {
+ return;
+ }
+
+ fseek(fp_in, 0, SEEK_END);
+ long size = ftell(fp_in);
+ fseek(fp_in, 0, SEEK_SET);
+ if (size <= 0) {
+ fclose(fp_in);
+ return;
+ }
+
+ char* data = reinterpret_cast<char *>(calloc(sizeof(char), size));
+ if (NULL == data) {
+ fclose(fp_in);
+ return;
+ }
+
+ size_t read_size = fread(data, sizeof(char), size, fp_in);
+ fclose(fp_in);
+
+ if (read_size <= 0) {
+ free(data);
+ return;
+ }
+
+ mPCMSize = size;
+ mPCMData = data;
+}
+
+void TtsTestUtility::CreateHandle()
+{
+ if (IsFeatureSupported() == false) {
+ mHandle = nullptr;
+ return;
+ }
+
+ tts_create(&mHandle);
+ ASSERT_NE(mHandle, nullptr);
+
+ EXPECT_EQ(tts_set_state_changed_cb(mHandle, StateChangedCallback, this), TTS_ERROR_NONE);
+ EXPECT_EQ(tts_set_service_state_changed_cb(mHandle, ServiceStateChangedCallback, this), TTS_ERROR_NONE);
+ EXPECT_EQ(tts_set_error_cb(mHandle, ErrorCallback, this), TTS_ERROR_NONE);
+ EXPECT_EQ(tts_get_default_voice(mHandle, &mLanguage, &mVoiceType), TTS_ERROR_NONE);
+}
+
+void TtsTestUtility::DestroyHandle()
+{
+ if (nullptr != mHandle) {
+ EXPECT_EQ(tts_destroy(mHandle), TTS_ERROR_NONE);
+ mHandle = nullptr;
+ }
+}
+
+bool TtsTestUtility::IsStateChanged(tts_state_e targetState, int duration)
+{
+ auto stateChecker = std::bind([](TtsTestUtility *instance, tts_state_e target) {
+ return target == instance->mCurrentState;
+ }, this, targetState);
+
+ return WaitCondtion(stateChecker, duration);
+}
+
+bool TtsTestUtility::IsServiceStateChanged(tts_service_state_e targetState, int duration)
+{
+ auto stateChecker = std::bind([](TtsTestUtility *instance, tts_service_state_e target) {
+ return target == instance->mCurrentServiceState;
+ }, this, targetState);
+
+ return WaitCondtion(stateChecker, duration);
+}
+
+bool TtsTestUtility::IsScreenReaderOn(int duration)
+{
+ auto screenReaderChecker = std::bind([](TtsTestUtility *instance) {
+ return instance->mScreenReaderOn;
+ }, this);
+
+ return WaitCondtion(screenReaderChecker, duration);
+}
+
+bool TtsTestUtility::IsUtteranceStarted(int duration)
+{
+ auto utteranceChecker = std::bind([](TtsTestUtility *instance) {
+ return instance->mUtteranceStarted;
+ }, this);
+
+ return WaitCondtion(utteranceChecker, duration);
+}
+
+bool TtsTestUtility::IsUtteranceCompleted(int duration)
+{
+ auto utteranceChecker = std::bind([](TtsTestUtility *instance) {
+ return instance->mUtteranceCompleted;
+ }, this);
+
+ return WaitCondtion(utteranceChecker, duration);
+}
+
+bool TtsTestUtility::IsErrorOccurring(int duration)
+{
+ auto errorChecker = std::bind([](TtsTestUtility *instance) {
+ return instance->mErrorOccured;
+ }, this);
+
+ return WaitCondtion(errorChecker, duration);
+}
+
+bool TtsTestUtility::Prepare()
+{
+ tts_state_e state = TTS_STATE_CREATED;
+ tts_get_state(mHandle, &state);
+ if (TTS_STATE_CREATED != state) {
+ return false;
+ }
+
+ tts_prepare(mHandle);
+ return IsStateChanged(TTS_STATE_READY, 5);
+}
+
+bool TtsTestUtility::Unprepare()
+{
+ tts_state_e state = TTS_STATE_CREATED;
+ tts_get_state(mHandle, &state);
+ if (TTS_STATE_READY != state) {
+ return false;
+ }
+
+ tts_unprepare(mHandle);
+ return IsStateChanged(TTS_STATE_CREATED, 5);
+}
+
+bool TtsTestUtility::Play()
+{
+ EXPECT_EQ(tts_play(mHandle), TTS_ERROR_NONE);
+ return IsStateChanged(TTS_STATE_PLAYING, 5);
+}
+
+bool TtsTestUtility::Pause()
+{
+ EXPECT_EQ(tts_pause(mHandle), TTS_ERROR_NONE);
+ return IsStateChanged(TTS_STATE_PAUSED, 5);
+}
+
+bool TtsTestUtility::Stop()
+{
+ EXPECT_EQ(tts_stop(mHandle), TTS_ERROR_NONE);
+ return IsStateChanged(TTS_STATE_READY, 5);
+}
+
+bool TtsTestUtility::WaitCondtion(std::function<bool(void)> checker, int duration)
+{
+ auto mainLoopQuitTimer = ecore_timer_add(static_cast<double>(duration), [](void *data) -> Eina_Bool {
+ ecore_main_loop_quit();
+ return EINA_FALSE;
+ }, nullptr);
+
+ auto checkerTimer = ecore_timer_add(0.0, [](void *data) -> Eina_Bool {
+ auto &checker = *reinterpret_cast<std::function<bool()> *>(data);
+ if (false == checker()) {
+ return EINA_TRUE;
+ }
+
+ ecore_main_loop_quit();
+ return EINA_FALSE;
+ }, &checker);
+
+ if (nullptr == mainLoopQuitTimer || nullptr == checkerTimer) {
+ return false;
+ }
+
+ ecore_main_loop_begin();
+
+ ecore_timer_del(mainLoopQuitTimer);
+ mainLoopQuitTimer = nullptr;
+
+ ecore_timer_del(checkerTimer);
+ checkerTimer = nullptr;
+
+ return checker();
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 __TTS_TEST_UTIL_H__
+#define __TTS_TEST_UTIL_H__
+
+
+#include <tts.h>
+#include <tts_internal.h>
+
+
+class TtsTestUtility {
+public:
+ static void StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data);
+ static void ServiceStateChangedCallback(tts_h tts, tts_service_state_e previous, tts_service_state_e current, void* user_data);
+ static void ScreenReaderChangedCallback(tts_h tts, bool is_on, void* user_data);
+ static void UtteranceStartedCallback(tts_h tts, int utt_id, void* user_data);
+ static void UtteranceCompletedCallback(tts_h tts, int utt_id, void *user_data);
+ static void ErrorCallback(tts_h tts, int utt_id, tts_error_e reason, void* user_data);
+
+ static void TerminateCurrentEngine();
+ static void WaitUntilEngineTerminated(int duration);
+ static bool IsFeatureSupported();
+
+public:
+ TtsTestUtility();
+ ~TtsTestUtility();
+
+ void GetTestPCMData();
+
+ void CreateHandle();
+ void DestroyHandle();
+
+ bool Prepare();
+ bool Unprepare();
+
+ bool Play();
+ bool Pause();
+ bool Stop();
+
+ bool IsStateChanged(tts_state_e targetState, int duration);
+ bool IsServiceStateChanged(tts_service_state_e targetState, int duration);
+ bool IsScreenReaderOn(int duration);
+ bool IsUtteranceStarted(int duration);
+ bool IsUtteranceCompleted(int duration);
+ bool IsErrorOccurring(int duration);
+
+public:
+ tts_h mHandle;
+ tts_state_e mCurrentState;
+ tts_service_state_e mCurrentServiceState;
+
+ char *mLanguage;
+ int mVoiceType;
+ bool mScreenReaderOn;
+ bool mUtteranceStarted;
+ bool mUtteranceCompleted;
+ bool mErrorOccured;
+ int mUttId;
+
+ char* mPCMData;
+ size_t mPCMSize;
+
+private:
+ static bool WaitCondtion(std::function<bool(void)> checker, int duration);
+};
+
+
+#endif /* __TTS_TEST_UTIL_H__ */