From: sooyeon Date: Fri, 29 Mar 2024 08:33:48 +0000 (+0900) Subject: Pause default mode's tts playing when sound focus is released X-Git-Tag: accepted/tizen/7.0/unified/20240405.012350~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F33%2F308733%2F3;p=platform%2Fcore%2Fuifw%2Ftts.git Pause default mode's tts playing when sound focus is released - Issue: In Tizen 7.0 FHub, TTS sound and ringtone are mixed, because TTS is not paused, although the sound focus is released. - Solution: Add a logic to pause tts playing when the sound focus is released in default mode. Change-Id: Icd4615bf9af8c56197b7bf43df2cbab9284620a3 Signed-off-by: sooyeon --- diff --git a/server/AudioStream.cpp b/server/AudioStream.cpp index 2e80c3fb..538d8667 100644 --- a/server/AudioStream.cpp +++ b/server/AudioStream.cpp @@ -23,14 +23,15 @@ using namespace std; static const char* FOCUS_SERVER_READY = "/tmp/.focus_server_ready"; -AudioStream::AudioStream(): +AudioStream::AudioStream(FocusReleasedCallback focusReleasedCb): __audioHandle(nullptr), __audioType(TTSE_AUDIO_TYPE_RAW_S16), __audioRate(16000), __prepared(false), __streamInfo(nullptr), __focusAquired(false), - __state(AUDIO_STATE_NONE) + __state(AUDIO_STATE_NONE), + __focusReleasedCb(focusReleasedCb) { createSoundStreamInfo(); createAudioHandle(__audioType, __audioRate); @@ -332,4 +333,21 @@ void AudioStream::__focusStateChangedCallback(sound_stream_info_h stream_info, s { SLOG(LOG_INFO, tts_tag(), "[AudioStream] focus state changed to (%d) with reason(%d) and extra info(%s)", (int)focus_state, (int)reason_for_change, extra_info); + + AudioStream *temp = (AudioStream*)user_data; + + if (temp->__streamInfo != stream_info) { + SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Invalid stream info handle"); + return; + } + + if ((AUDIO_STATE_PLAY == temp->__state || AUDIO_STATE_WAIT_FOR_PLAYING == temp->__state) && SOUND_STREAM_FOCUS_FOR_PLAYBACK == focus_mask && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) { + /* invoke focusReleasedCb registered by ttsd_player */ + temp->__state = AUDIO_STATE_READY; + temp->__focusReleasedCb(); + } + + SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Finish to invoke focusReleasedCb"); + + return; } diff --git a/server/AudioStream.h b/server/AudioStream.h index bddb88bb..d703d0d1 100644 --- a/server/AudioStream.h +++ b/server/AudioStream.h @@ -31,7 +31,9 @@ public: AUDIO_STATE_PLAY }; - AudioStream(); + typedef void (*FocusReleasedCallback)(void); + + AudioStream(FocusReleasedCallback focusReleasedCb); ~AudioStream(); int setAudioFormat(ttse_audio_type_e type, int rate); @@ -68,6 +70,7 @@ private: bool __focusAquired; AudioState __state; + FocusReleasedCallback __focusReleasedCb; }; diff --git a/server/ttsd_player.cpp b/server/ttsd_player.cpp index 195a6c5f..f7670c48 100644 --- a/server/ttsd_player.cpp +++ b/server/ttsd_player.cpp @@ -411,13 +411,49 @@ static void __play_utterance_cb(PlayerThread* player, unsigned int uid) SLOG(LOG_DEBUG, tts_tag(), "[PLAYER] Finish play utterance. uid(%u)", uid); } +static void __focus_released_cb(void) +{ + SLOG(LOG_INFO, tts_tag(), "[PLAYER] __focus_released_cb is invoked"); + + unsigned int currentUid = g_player_thread->getCurrentUid(); + ttsd_mode_e mode = ttsd_data_get_mode(currentUid); + + if (TTSD_MODE_DEFAULT != mode) { + SLOG(LOG_WARN, tts_tag(), "[PLAYER] Ignore focus released callback. mode of the current playing uid(%d)", mode); + return; + } + + app_tts_state_e state = ttsd_data_get_client_state(currentUid); + if (APP_STATE_NONE == state) { + SLOG(LOG_ERROR, tts_tag(), "[PLAYER ERROR] uid is not valid"); + return; + } + + if (APP_STATE_PLAYING == state) { + /* pause player */ + ttsd_data_set_client_state(currentUid, APP_STATE_PAUSED); + if (TTSD_ERROR_NONE != ttsd_player_pause(currentUid)) { + SLOG(LOG_WARN, tts_tag(), "[PLAYER] Fail to ttsd_player_pause()"); + return; + } + } + + int pid = ttsd_data_get_pid(currentUid); + if (pid <= 0) { + SLOG(LOG_ERROR, tts_tag(), "[PLAYER ERROR] Fail to get pid. uid(%u)", currentUid); + return; + } else { + ttsdc_ipc_send_set_state_message(pid, currentUid, APP_STATE_PAUSED); + } +} + /* * Player Interfaces */ int ttsd_player_init() { g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION); - g_audio_stream = new AudioStream(); + g_audio_stream = new AudioStream(__focus_released_cb); g_player_thread = new PlayerThread(__play_utterance_cb); g_is_set_policy = false; diff --git a/server/ttsd_server.c b/server/ttsd_server.c index 7c86be78..5cb5e7f0 100644 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -67,6 +67,25 @@ static bool g_is_terminated = false; static int g_activated_mode = 0; /* Function definitions */ +static int __pause_and_send_ready_state(unsigned int uid) +{ + int ret = ttsd_server_pause(uid); + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_server_pause() : uid(%u). ret(%d)", uid, ret); + return ret; + } + + int pid = ttsd_data_get_pid(uid); + if (pid <= 0) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to get pid. uid(%u)", uid); + return TTSD_ERROR_OPERATION_FAILED; + } else { + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED); + } + + return ret; +} + static int __stop_and_send_ready_state(unsigned int uid) { int ret = ttsd_server_stop(uid); @@ -1047,6 +1066,10 @@ static int __interrupt_player_by_policy(unsigned int request_app_uid) ttsd_mode_e playing_app_mode = ttsd_data_get_mode(playing_app_uid); switch (playing_app_mode) { case TTSD_MODE_DEFAULT: + SLOG(LOG_DEBUG, tts_tag(), "[Server] Played client(%u) will be interrupted into 'Pause' state", playing_app_uid); + __pause_and_send_ready_state(playing_app_uid); + break; + case TTSD_MODE_NOTIFICATION: case TTSD_MODE_SCREEN_READER: SLOG(LOG_DEBUG, tts_tag(), "[Server] Played client(%u) will be interrupted into 'Stop' state", playing_app_uid);