Pause default mode's tts playing when sound focus is released 33/308733/3
authorsooyeon <sooyeon.kim@samsung.com>
Fri, 29 Mar 2024 08:33:48 +0000 (17:33 +0900)
committersooyeon <sooyeon.kim@samsung.com>
Thu, 4 Apr 2024 05:00:41 +0000 (14:00 +0900)
- 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 <sooyeon.kim@samsung.com>
server/AudioStream.cpp
server/AudioStream.h
server/ttsd_player.cpp
server/ttsd_server.c

index 2e80c3fb43796631b61498e57a4780f5c70ed55e..538d8667b242d077e0c1f0324e7908490cef3060 100644 (file)
@@ -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;
 }
index bddb88bb7f8a6299ada1e31d96e375fba958de72..d703d0d14362cceb958cb30bd5acb006df9b4c9c 100644 (file)
@@ -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;
 };
 
 
index 195a6c5fc00f1460487e1e171f67c4c9553ed06e..f7670c48e619d65784e0c7490225aea7e43bf4f1 100644 (file)
@@ -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;
index 7c86be7839db7c989346e8464bda70baf0102788..5cb5e7f0b6aa60fea0f700913c36b394efed7ee7 100644 (file)
@@ -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);