+void __player_focus_state_watch_cb(int id, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason,
+ const char *extra_info, void *user_data)
+{
+ SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state watch cb");
+
+ ttsd_mode_e mode = ttsd_get_mode();
+
+ if (TTSD_MODE_SCREEN_READER != mode && TTSD_MODE_NOTIFICATION != mode) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] This is not screen-reader mode and notification mode.");
+ return;
+ }
+
+ if (NULL == g_playing_info) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+ return;
+ }
+
+ if (APP_STATE_PLAYING == g_playing_info->state && SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION == reason &&
+ NULL != extra_info && 0 == strncmp(extra_info, "TTSD_MODE_INTERRUPT", strlen(extra_info))) {
+ /* If the focus is changed by "Interrupt" mode and current players of "SR" and "Noti" modes are on going, please stop the current players. */
+ g_audio_state = AUDIO_STATE_READY;
+
+ int uid = g_playing_info->uid;
+
+ if (0 != ttsd_server_stop(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop TTS server");
+ return;
+ }
+ if (0 != ttsd_player_stop(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop the player");
+ return;
+ }
+
+ ttsd_data_set_client_state(uid, APP_STATE_READY);
+ int pid = ttsd_data_get_pid(uid);
+ /* send message to client about changing state */
+ ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Extra info is not Interrupt mode(%s) or not playing state(%d).", extra_info, g_playing_info->state);
+ }
+
+ 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_DEBUG, tts_tag(), "[Player] is ducked : %d", is_ducked);
+ // ducking_flag = true;
+ return;
+}
+
+static char* __get_ducking_stream(sound_stream_type_e stream_type)
+{
+ if (SOUND_STREAM_TYPE_MEDIA == stream_type)
+ return "Media stream";
+ else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
+ return "System stream";
+ else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
+ return "Notification stream";
+ else if (SOUND_STREAM_TYPE_ALARM == stream_type)
+ return "Alarm stream";
+ return "Non matched stream";
+}
+
+static int __activate_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 ducked", __get_ducking_stream(stream_type));
+ } else {
+ ret = sound_manager_activate_ducking(stream_ducking_h, SND_MGR_DUCKING_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()
+{
+ 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);
+ __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
+ __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
+ __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
+ }
+}
+
+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);
+}
+