Merge "Fix potential defects on ttsd_player" into tizen
[platform/core/uifw/tts.git] / server / ttsd_player.cpp
index 80b3a80..3547454 100644 (file)
@@ -14,9 +14,7 @@
 #include <audio_io.h>
 #include <Ecore.h>
 #include <sound_manager.h>
-#include <sound_manager_internal.h>
 #include <pthread.h>
-#include <time.h>
 
 #include "ttsd_main.h"
 #include "ttsd_player.h"
@@ -24,6 +22,8 @@
 #include "ttsd_dbus.h"
 #include "ttsd_ipc.h"
 
+#include "BackgroundVolume.h"
+
 #include "tts_internal.h"
 #include "ttsd_server.h"
 
@@ -88,31 +88,21 @@ static audio_out_h g_audio_h;
 
 static sound_stream_info_h g_stream_info_h;
 
-static sound_stream_ducking_h g_media_stream_ducking;
-//static sound_stream_ducking_h g_system_stream_ducking;
-static sound_stream_ducking_h g_notification_stream_ducking;
-static sound_stream_ducking_h g_alarm_stream_ducking;
-
 static bool g_is_set_policy;
 
-// static bool ducking_flag;
-
 /* CAUTION!
 If you change this constant value. Please check the function '__set_timer_for_delay_recover()'.
 If you choose too big value, it may cause integer overflow issue.
 */
 #define SND_MGR_DUCKING_DURATION 500
 
-static struct timespec g_policy_set_time;
-static Ecore_Timer* g_delayed_unset_policy_timer = NULL;
-static Ecore_Timer* g_modify_background_volume = NULL;
-
-static double g_bg_volume_ratio;
-
 static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
+
+static BackgroundVolume* g_background_volume = nullptr;
+
 /*
 * Internal Interfaces
 */
@@ -313,90 +303,6 @@ static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_strea
        return;
 }
 
-void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
-{
-       SLOG(LOG_DEBUG, tts_tag(), "@@@ ducking state changed cb");
-       SLOG(LOG_ERROR, tts_tag(), "[Player] ducking_h(%p) is ducked : %d", stream_ducking, is_ducked);
-       // ducking_flag = true;
-       return;
-}
-
-static const char* __get_ducking_stream(sound_stream_type_e stream_type)
-{
-       const char* type = nullptr;
-       if (SOUND_STREAM_TYPE_MEDIA == stream_type)
-               type = "Media stream";
-       else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
-               type = "System stream";
-       else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
-               type = "Notification stream";
-       else if (SOUND_STREAM_TYPE_ALARM == stream_type)
-               type = "Alarm stream";
-       else
-               type = "Non matched stream";
-
-       return type;
-}
-
-static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, unsigned int duration)
-{
-       bool is_ducked = false;
-       int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
-       if (is_ducked) {
-               SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already ducked", __get_ducking_stream(stream_type));
-       } else {
-               ret = sound_manager_activate_ducking(stream_ducking_h, duration, g_bg_volume_ratio);
-               if (SOUND_MANAGER_ERROR_NONE != ret) {
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
-               } else {
-                       SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
-               }
-       }
-       return ret;
-}
-
-static void __change_background_volume(unsigned int duration)
-{
-       SLOG(LOG_INFO, tts_tag(), "[BG] Change background volume");
-       SLOG(LOG_INFO, tts_tag(), "[Player] volume ratio(%lf)", g_bg_volume_ratio);
-       if (1.0 > g_bg_volume_ratio) {
-               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking, duration);
-//             __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, duration);
-               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, duration);
-               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, duration);
-       }
-}
-
-static void __change_background_volume_async(void* data)
-{
-       __change_background_volume(SND_MGR_DUCKING_DURATION);
-}
-
-static int __deactivate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
-{
-       bool is_ducked = false;
-       int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
-       if (!is_ducked) {
-               SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already recovered from ducking", __get_ducking_stream(stream_type));
-       } else {
-               ret = sound_manager_deactivate_ducking(stream_ducking_h);
-               if (SOUND_MANAGER_ERROR_NONE != ret) {
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
-               } else {
-                       SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
-               }
-       }
-       return ret;
-}
-
-static void __recover_background_volume()
-{
-       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
-//     __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
-       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
-       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
-}
-
 static int __create_audio_out(ttse_audio_type_e type, int rate)
 {
        int ret = -1;
@@ -456,19 +362,8 @@ static void __end_play_thread(void *data, Ecore_Thread *thread)
        SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
 }
 
-static void __del_timer_for_delayed_recover(void* data)
-{
-       if (NULL != g_delayed_unset_policy_timer) {
-               int result = (intptr_t)ecore_timer_del(g_delayed_unset_policy_timer);
-               g_delayed_unset_policy_timer = NULL;
-               SLOG(LOG_ERROR, tts_tag(), "[BG] Remove timer (%d)", result);
-       }
-}
-
 static void __set_policy_for_playing(void)
 {
-       ecore_main_loop_thread_safe_call_async(__del_timer_for_delayed_recover, NULL);
-
        /* Set stream info */
        const char* extra_info = NULL;
        if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) {
@@ -487,56 +382,14 @@ static void __set_policy_for_playing(void)
                SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
        }
 
-       ecore_main_loop_thread_safe_call_async(__change_background_volume_async, NULL);
-
+       g_background_volume->applyVolumeRatio();
        g_is_set_policy = true;
        SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
-
-       clock_gettime(CLOCK_MONOTONIC, &g_policy_set_time);
-
        SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
 
        return;
 }
 
-static Eina_Bool __delay_recover_background_volume(void* data)
-{
-       __recover_background_volume();
-       SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy success");
-
-       g_delayed_unset_policy_timer = NULL;
-       return EINA_FALSE;
-}
-
-static long long int __get_duration_from_last_volume_change()
-{
-       struct timespec current_time;
-       clock_gettime(CLOCK_MONOTONIC, &current_time);
-
-       long long int diff = ((long long int)current_time.tv_sec - (long long int)g_policy_set_time.tv_sec) * 1000
-                       + ((long long int)current_time.tv_nsec - (long long int)g_policy_set_time.tv_nsec) / 1000000;
-       SLOG(LOG_INFO, tts_tag(), "[BG] Time Diff(%lld)", diff);
-
-       return diff;
-}
-
-static void __set_timer_for_delay_recover(void* data)
-{
-       if (NULL != g_delayed_unset_policy_timer) {
-               return;
-       }
-
-       long long int diff = __get_duration_from_last_volume_change();
-       if (diff > SND_MGR_DUCKING_DURATION) {
-               SLOG(LOG_INFO, tts_tag(), "[BG] Direct unset policy");
-               __recover_background_volume();
-       } else {
-               double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
-               g_delayed_unset_policy_timer = ecore_timer_add(delay, __delay_recover_background_volume, (void*)CHECK_TIMER_DELETE);
-               SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy (%p), delay(%f)", g_delayed_unset_policy_timer, delay);
-       }
-}
-
 static void __unset_policy_for_playing()
 {
        /* Unset stream info */
@@ -554,8 +407,7 @@ static void __unset_policy_for_playing()
                }
        }
 
-       ecore_main_loop_thread_safe_call_async(__set_timer_for_delay_recover, NULL);
-
+       g_background_volume->recoverVolumeRatio();
        g_is_set_policy = false;
        SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
        SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
@@ -996,44 +848,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
        }
 }
 
-int __create_ducking_handle(void)
-{
-       int ret = -1;
-       if (NULL == g_media_stream_ducking) {
-               ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_media_stream_ducking);
-               if (SOUND_MANAGER_ERROR_NONE != ret)
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
-       } else {
-               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for media stream is already created");
-       }
-
-/*     if (NULL == g_system_stream_ducking) {
-               ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_SYSTEM, __sound_stream_ducking_state_changed_cb, NULL, &g_system_stream_ducking);
-               if (SOUND_MANAGER_ERROR_NONE != ret)
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
-       } else {
-               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for system stream is already created");
-       }
-*/
-       if (NULL == g_notification_stream_ducking) {
-               ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, NULL, &g_notification_stream_ducking);
-               if (SOUND_MANAGER_ERROR_NONE != ret)
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
-       } else {
-               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for notification stream is already created");
-       }
-
-       if (NULL == g_alarm_stream_ducking) {
-               ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, NULL, &g_alarm_stream_ducking);
-               if (SOUND_MANAGER_ERROR_NONE != ret)
-                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
-       } else {
-               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for alarm stream is already created");
-       }
-
-       return ret;
-}
-
 /*
 * Player Interfaces
 */
@@ -1069,12 +883,7 @@ int ttsd_player_init()
                SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
        }
 
-       ret = __create_ducking_handle();
-       if (SOUND_MANAGER_ERROR_NONE != ret) {
-               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create ducking handle, ret(%d)", ret);
-       } else {
-               SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Create ducking handle");
-       }
+       g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION);
 
        ecore_thread_max_set(1);
 
@@ -1089,6 +898,7 @@ int ttsd_player_init()
 
        ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
 
+       g_is_set_policy = false;
        g_player_init = true;
 
        pthread_mutex_unlock(&g_player_control_mutex);
@@ -1096,41 +906,6 @@ int ttsd_player_init()
        return 0;
 }
 
-static void __destroy_all_ducking_handles()
-{
-       SLOG(LOG_INFO, tts_tag(), "[Player] Destroy stream ducking");
-       if (__get_duration_from_last_volume_change() <= SND_MGR_DUCKING_DURATION) {
-               usleep(500000);
-       }
-
-       __recover_background_volume();
-
-       int ret = -1;
-       ret = sound_manager_destroy_stream_ducking(g_media_stream_ducking);
-       if (SOUND_MANAGER_ERROR_NONE != ret) {
-               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
-       }
-       g_media_stream_ducking = NULL;
-
-/*     ret = sound_manager_destroy_stream_ducking(g_system_stream_ducking);
-       if (SOUND_MANAGER_ERROR_NONE != ret) {
-               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
-       }
-       g_system_stream_ducking = NULL;
-*/
-       ret = sound_manager_destroy_stream_ducking(g_notification_stream_ducking);
-       if (SOUND_MANAGER_ERROR_NONE != ret) {
-               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
-       }
-       g_notification_stream_ducking = NULL;
-
-       ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
-       if (SOUND_MANAGER_ERROR_NONE != ret) {
-               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
-       }
-       g_alarm_stream_ducking = NULL;
-}
-
 int ttsd_player_release(void)
 {
 #ifdef BUF_SAVE_MODE
@@ -1181,8 +956,6 @@ int ttsd_player_release(void)
                SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
        }
 
-       __destroy_all_ducking_handles();
-
        /* clear g_player_list */
        g_playing_info = NULL;
        g_player_init = false;
@@ -1190,6 +963,9 @@ int ttsd_player_release(void)
 
        g_stream_info_h = NULL;
 
+       delete g_background_volume;
+       g_background_volume = nullptr;
+
        pthread_mutex_unlock(&g_player_control_mutex);
 
        return 0;
@@ -1552,47 +1328,12 @@ int ttsd_player_get_background_volume_ratio(double* ratio)
                return TTSD_ERROR_OPERATION_FAILED;
        }
 
-       if (NULL == ratio)
-               return -1;
-       else
-               *ratio = g_bg_volume_ratio;
-
-       return TTSD_ERROR_NONE;
-}
-
-static Eina_Bool __modify_background_volume_async(void* data)
-{
-       __recover_background_volume();
-       __change_background_volume(0);
-       SLOG(LOG_INFO, tts_tag(), "[BG] Modify background volume with delay");
-
-       g_modify_background_volume = NULL;
-       return EINA_FALSE;
-}
-
-static void __modify_background_volume(void* data)
-{
-       if (NULL != g_delayed_unset_policy_timer) {
-               SLOG(LOG_INFO, tts_tag(), "[BG] Background volume is going to recover soon. Skip modification");
-               return;
-       }
-
-       if (NULL != g_modify_background_volume) {
-               int result = (intptr_t)ecore_timer_del(g_modify_background_volume);
-               g_modify_background_volume = NULL;
-               SLOG(LOG_ERROR, tts_tag(), "[BG] Remove modify background volume timer (%d)", result);
+       if (NULL == ratio) {
+               return TTSD_ERROR_INVALID_PARAMETER;
        }
 
-       long long int diff = __get_duration_from_last_volume_change();
-       if (diff > SND_MGR_DUCKING_DURATION) {
-               __recover_background_volume();
-               __change_background_volume(0);
-               SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
-       } else {
-               double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
-               g_modify_background_volume = ecore_timer_add(delay, __modify_background_volume_async, (void*)CHECK_TIMER_DELETE);
-               SLOG(LOG_INFO, tts_tag(), "[BG] Delay modifying background volume (%p), delay(%f)", g_modify_background_volume, delay);
-       }
+       *ratio = g_background_volume->getVolumeRatio();
+       return TTSD_ERROR_NONE;
 }
 
 int ttsd_player_set_background_volume_ratio(double ratio)
@@ -1603,19 +1344,7 @@ int ttsd_player_set_background_volume_ratio(double ratio)
        }
 
        SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
-
-       double prev_ratio = g_bg_volume_ratio;
-       g_bg_volume_ratio = ratio;
-
-       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Check whether sound is ducked and Change volume. as-is(%lf), to-be(%lf)", prev_ratio, g_bg_volume_ratio);
-       if (prev_ratio == g_bg_volume_ratio) {
-               return TTSD_ERROR_NONE;
-       }
-
-       if (g_is_set_policy) {
-               SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
-               ecore_main_loop_thread_safe_call_async(__modify_background_volume, NULL);
-       }
+       g_background_volume->setVolumeRatio(ratio);
 
        return TTSD_ERROR_NONE;
 }