Fix build warning
[platform/core/api/audio-io.git] / src / cpp / CAudioIO.cpp
index 71f38fe..0de125b 100644 (file)
@@ -18,6 +18,7 @@
 #include <mm.h>
 #include <pthread.h>
 #include <assert.h>
+#include <glib.h>
 #include "CAudioIODef.h"
 
 using namespace std;
@@ -31,25 +32,33 @@ CAudioIO::CAudioIO() :
     mpAudioSessionHandler(NULL),
     mpPulseAudioClient(NULL),
     __mMutex(PTHREAD_MUTEX_INITIALIZER),
+    __mCondMutex(PTHREAD_MUTEX_INITIALIZER),
     __mCond(PTHREAD_COND_INITIALIZER),
     __mIsInit(false),
     __mForceIgnore(false) {
+    mInterruptCode = IAudioSessionEventListener::EInterruptCode::INTERRUPT_MAX;
+    mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_MAX;
     mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mByPolicy = false;
+    mIsInterrupted = false;
 }
 
 CAudioIO::CAudioIO(CAudioInfo& audioInfo) :
     mpAudioSessionHandler(NULL),
     mpPulseAudioClient(NULL),
     __mMutex(PTHREAD_MUTEX_INITIALIZER),
+    __mCondMutex(PTHREAD_MUTEX_INITIALIZER),
     __mCond(PTHREAD_COND_INITIALIZER),
     __mIsInit(false),
     __mForceIgnore(false) {
     mAudioInfo = audioInfo;
+    mInterruptCode = IAudioSessionEventListener::EInterruptCode::INTERRUPT_MAX;
+    mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_MAX;
     mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mByPolicy = false;
+    mIsInterrupted = false;
 }
 
 CAudioIO::~CAudioIO() {
@@ -67,7 +76,7 @@ bool CAudioIO::IsReady() {
     return ((mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING || mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED)? true : false);
 }
 
-void CAudioIO::internalLock() throw(CAudioError) {
+void CAudioIO::internalLock() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -75,12 +84,13 @@ void CAudioIO::internalLock() throw(CAudioError) {
     if (pthread_mutex_lock(&__mMutex) != 0) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
     }
+
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-    AUDIO_IO_LOGD(COLOR_RED "LOCK" COLOR_END);
+    AUDIO_IO_LOGD(COLOR_RED "%p LOCKED" COLOR_END, &__mMutex);
 #endif
 }
 
-void CAudioIO::internalUnlock() throw(CAudioError) {
+void CAudioIO::internalUnlock() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -89,11 +99,11 @@ void CAudioIO::internalUnlock() throw(CAudioError) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
     }
 #ifdef _AUDIO_IO_DEBUG_TIMING_
-    AUDIO_IO_LOGD(COLOR_GREEN "UNLOCK" COLOR_END);
+    AUDIO_IO_LOGD(COLOR_GREEN "%p UNLOCKED" COLOR_END, &__mMutex);
 #endif
 }
 
-void CAudioIO::internalWait() throw(CAudioError) {
+void CAudioIO::internalWait() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -102,10 +112,12 @@ void CAudioIO::internalWait() throw(CAudioError) {
     AUDIO_IO_LOGD(COLOR_RED "WAIT" COLOR_END);
 #endif
 
-    pthread_cond_wait(&__mCond, &__mMutex);
+    pthread_mutex_lock(&__mCondMutex);
+    pthread_cond_wait(&__mCond, &__mCondMutex);
+    pthread_mutex_unlock(&__mCondMutex);
 }
 
-void CAudioIO::internalSignal() throw(CAudioError) {
+void CAudioIO::internalSignal() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -114,14 +126,16 @@ void CAudioIO::internalSignal() throw(CAudioError) {
     AUDIO_IO_LOGD(COLOR_GREEN "SIGNAL" COLOR_END);
 #endif
 
+    pthread_mutex_lock(&__mCondMutex);
     pthread_cond_signal(&__mCond);
+    pthread_mutex_unlock(&__mCondMutex);
 }
 
 bool CAudioIO::isForceIgnore() {
     return __mForceIgnore;
 }
 
-void CAudioIO::initialize() throw(CAudioError) {
+void CAudioIO::initialize() {
     if (__mIsInit == true) {
         return;
     }
@@ -148,16 +162,28 @@ void CAudioIO::finalize() {
 
     AUDIO_IO_LOGD("finalize");
 
+    bool error_occured = false;
     int ret = pthread_mutex_destroy(&__mMutex);
     if (ret != 0) {
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_destroy() ret:%d", ret);
+        AUDIO_IO_LOGE("Failed pthread_mutex_destroy(%p) errno:%d", &__mMutex, ret);
+        error_occured = true;
+    }
+    ret = pthread_mutex_destroy(&__mCondMutex);
+    if (ret != 0) {
+        AUDIO_IO_LOGE("Failed pthread_mutex_destroy(%p) errno:%d", &__mCondMutex, ret);
+        error_occured = true;
     }
 
+
     ret = pthread_cond_destroy(&__mCond);
     if (ret != 0) {
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_destroy() ret:%d", ret);
+        AUDIO_IO_LOGE("Failed pthread_cond_destroy(%p) errno:%d", &__mCond, ret);
+        error_occured = true;
     }
 
+    if (error_occured)
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Finalize Failed");
+
     __mIsInit = false;
 }
 
@@ -189,7 +215,11 @@ void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy) {
     const char* state_string[] = { "NONE", "IDLE", "RUNNING", "PAUSED" };
 
     AUDIO_IO_LOGD("previous(%s,%d) ===> current(%s,%d), by_policy(%d)",
-                  state_string[(int)mStatePrev], mStatePrev, state_string[(int)mState], mState, mByPolicy);
+                  state_string[static_cast<int>(mStatePrev)],
+                  static_cast<int>(mStatePrev),
+                  state_string[static_cast<int>(mState)],
+                  static_cast<int>(mState),
+                  mByPolicy);
 
     if (mStateChangedCallback.onStateChanged != NULL) {
         mStateChangedCallback.onStateChanged(mState, mStatePrev, mByPolicy, mStateChangedCallback.mUserData);
@@ -204,7 +234,23 @@ CAudioInfo::EAudioIOState CAudioIO::getState() {
     return mState;
 }
 
-void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) {
+int CAudioIO::sendInterrupt(void* user_data) {
+    CAudioIO *pCaudioIo = (CAudioIO *)user_data;
+
+    if (pCaudioIo && pCaudioIo->mInterruptCallback.onInterrupt) {
+        AUDIO_IO_LOGD("sending interrupt [%d]", static_cast<int>(pCaudioIo->mInterruptCode));
+        pCaudioIo->mInterruptCallback.onInterrupt(pCaudioIo->mInterruptCode, pCaudioIo->mInterruptCallback.mUserData);
+    }
+    return 0;
+}
+
+int caudio_gsource_callback(void *user_data) {
+    CAudioIO::sendInterrupt(user_data);
+    return 0;
+}
+
+void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type,
+                           mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) {
     assert(pHandler);
 
     int session_option = pHandler->getOptions();
@@ -220,29 +266,16 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
         }
 
         if (state == FOCUS_IS_RELEASED) {
-            // Focus handle(id) of the other application was released, do resume if possible
-            internalLock();
-
-            mpPulseAudioClient->cork(false);
-            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING);
-
-            internalUnlock();
-
+            // Focus handle(id) of the other application was released, notify resume
             // Focus watch callback doesn't have focus handle, but it need to convert & report to application for convenience
             state = FOCUS_IS_ACQUIRED;
         } else if (state == FOCUS_IS_ACQUIRED) {
             // Focus handle(id) of the other application was acquired, do pause if possible
             internalLock();
-
-            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_PLAYBACK) {
-                if (mpPulseAudioClient->drain() == false) {
-                    AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
-                }
+            if (mpPulseAudioClient) {
+                mpPulseAudioClient->cork(true);
             }
-
-            mpPulseAudioClient->cork(true);
-            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED);
-
+            mIsInterrupted = true;
             internalUnlock();
 
             // Focus watch callback doesn't have focus handle, but it need to convert & report to application for convenience
@@ -265,34 +298,29 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
         if (state == FOCUS_IS_RELEASED) {
             // Focus handle(id) was released, do pause here
             internalLock();
-
-            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_PLAYBACK) {
-                if (mpPulseAudioClient->drain() == false) {
-                    AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
-                }
+            if (mpPulseAudioClient) {
+                mpPulseAudioClient->cork(true);
             }
 
-            mpPulseAudioClient->cork(true);
-            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED);
-
+            mIsInterrupted = true;
             internalUnlock();
         } else if (state == FOCUS_IS_ACQUIRED) {
             // Focus handle(id) was acquired again,
             // check reason_for_change ("call-voice","call-video","voip","alarm","notification", ...)
             // do resume here and call interrupt completed callback to application.
-            internalLock();
-
-            mpPulseAudioClient->cork(false);
-            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING);
-
-            internalUnlock();
         }
     }
 
     if (mInterruptCallback.onInterrupt != NULL) {
         IAudioSessionEventListener::EInterruptCode e = IAudioSessionEventListener::EInterruptCode::INTERRUPT_COMPLETED;
         e = IAudioSessionEventListener::convertInterruptedCode(state, reason_for_change);
-        mInterruptCallback.onInterrupt(e, mInterruptCallback.mUserData);
+
+        if (EInterruptCode::INTERRUPT_COMPLETED == e) {
+            mInterruptCode = e;
+            g_idle_add(caudio_gsource_callback, this);
+        } else {
+            mInterruptCallback.onInterrupt(e, mInterruptCallback.mUserData);
+        }
     }
 }
 
@@ -310,20 +338,39 @@ void CAudioIO::onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t s
     }
 }
 
-void CAudioIO::prepare() throw(CAudioError) {
+void CAudioIO::prepare() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
-
+    if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN) {
+        AUDIO_IO_LOGD("Prepare for Audio in");
+    } else if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_OUT) {
+        AUDIO_IO_LOGD("Prepare for Audio Out");
+    }
     try {
+        if (mIsInterrupted) {
+            AUDIO_IO_LOGE("This is preparing during interrupted!!!");
+            bool isSkip = mpAudioSessionHandler->isSkipSession();
+            if (__mForceIgnore == false && isSkip == false && mpAudioSessionHandler->getId() >= 0) {
+                AUDIO_IO_LOGE("Session updatePlaying!!!");
+                mpAudioSessionHandler->updatePlaying();
+            }
+
+            if (mpPulseAudioClient && mpPulseAudioClient->isCorked()) {
+                AUDIO_IO_LOGE("Uncork!");
+                mpPulseAudioClient->cork(false);
+            }
+            mIsInterrupted = false;
+        }
+
         AUDIO_IO_LOGD("------> prepare done");
         /* Do nothing */
-    } catch (CAudioError e) {
-        throw e;
+    } catch (CAudioError& e) {
+        throw;
     }
 }
 
-void CAudioIO::unprepare() throw(CAudioError) {
+void CAudioIO::unprepare() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -331,12 +378,12 @@ void CAudioIO::unprepare() throw(CAudioError) {
     try {
         AUDIO_IO_LOGD("unprepare ----->");
         /* Do nothing */
-    } catch (CAudioError e) {
-        throw e;
+    } catch (CAudioError& e) {
+        throw;
     }
 }
 
-void CAudioIO::pause() throw(CAudioError) {
+void CAudioIO::pause() {
     if (__mIsInit == false || IsReady() == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
@@ -346,13 +393,13 @@ void CAudioIO::pause() throw(CAudioError) {
         AUDIO_IO_LOGD("pause");
         mpPulseAudioClient->cork(true);
         internalUnlock();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         internalUnlock();
-        throw e;
+        throw;
     }
 }
 
-void CAudioIO::resume() throw(CAudioError) {
+void CAudioIO::resume() {
     if (__mIsInit == false || IsReady() == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
@@ -362,13 +409,13 @@ void CAudioIO::resume() throw(CAudioError) {
         AUDIO_IO_LOGD("resume");
         mpPulseAudioClient->cork(false);
         internalUnlock();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         internalUnlock();
-        throw e;
+        throw;
     }
 }
 
-void CAudioIO::drain() throw(CAudioError) {
+void CAudioIO::drain() {
     if (__mIsInit == false || IsReady() == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
@@ -381,15 +428,15 @@ void CAudioIO::drain() throw(CAudioError) {
             mpPulseAudioClient->drain();
             internalUnlock();
         }
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         if (!mpPulseAudioClient->isInThread()) {
             internalUnlock();
         }
-        throw e;
+        throw;
     }
 }
 
-void CAudioIO::flush() throw(CAudioError) {
+void CAudioIO::flush() {
     if (__mIsInit == false || IsReady() == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
@@ -402,15 +449,15 @@ void CAudioIO::flush() throw(CAudioError) {
             mpPulseAudioClient->flush();
             internalUnlock();
         }
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         if (!mpPulseAudioClient->isInThread()) {
             internalUnlock();
         }
-        throw e;
+        throw;
     }
 }
 
-CAudioInfo& CAudioIO::getAudioInfo() throw(CAudioError) {
+CAudioInfo& CAudioIO::getAudioInfo() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -418,7 +465,7 @@ CAudioInfo& CAudioIO::getAudioInfo() throw(CAudioError) {
     return mAudioInfo;
 }
 
-void CAudioIO::setStreamCallback(SStreamCallback callback) throw(CAudioError) {
+void CAudioIO::setStreamCallback(SStreamCallback callback) {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -426,7 +473,7 @@ void CAudioIO::setStreamCallback(SStreamCallback callback) throw(CAudioError) {
     mStreamCallback = callback;
 }
 
-CAudioIO::SStreamCallback CAudioIO::getStreamCallback() throw(CAudioError) {
+CAudioIO::SStreamCallback CAudioIO::getStreamCallback() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -434,7 +481,7 @@ CAudioIO::SStreamCallback CAudioIO::getStreamCallback() throw(CAudioError) {
     return mStreamCallback;
 }
 
-void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) throw(CAudioError) {
+void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -442,7 +489,7 @@ void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) throw(CAu
     mStateChangedCallback = callback;
 }
 
-CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() throw(CAudioError) {
+CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -450,7 +497,7 @@ CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() throw(CAudio
     return mStateChangedCallback;
 }
 
-void CAudioIO::setInterruptCallback(SInterruptCallback callback) throw(CAudioError) {
+void CAudioIO::setInterruptCallback(SInterruptCallback callback) {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -458,7 +505,7 @@ void CAudioIO::setInterruptCallback(SInterruptCallback callback) throw(CAudioErr
     mInterruptCallback = callback;
 }
 
-CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() throw(CAudioError) {
+CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() {
     if (__mIsInit == false) {
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
@@ -466,7 +513,7 @@ CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() throw(CAudioError)
     return mInterruptCallback;
 }
 
-void CAudioIO::ignoreSession() throw(CAudioError) {
+void CAudioIO::ignoreSession() {
     if (__mIsInit == false)
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
 
@@ -476,21 +523,16 @@ void CAudioIO::ignoreSession() throw(CAudioError) {
         if (mpPulseAudioClient != NULL && mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING)
             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "An Operation is not permitted while started");
 
-        bool isSkip = mpAudioSessionHandler->isSkipSession();
-        if (isSkip == false && mpAudioSessionHandler->getId() >= 0)
-            mpAudioSessionHandler->unregisterSound();
-
-        mpAudioSessionHandler->finalize();
-        __mForceIgnore = true;
+        abandonInternalFocus();
 
         internalUnlock();
-    } catch (CAudioError e) {
+    } catch (CAudioError& e) {
         internalUnlock();
-        throw e;
+        throw;
     }
 }
 
-void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) throw(CAudioError) {
+void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) {
     if (stream_info == NULL)
         THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_ARGUMENT, "stream_info is NULL");
 
@@ -501,6 +543,8 @@ void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) throw(CAudioError)
         if (mState != CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE)
             THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_STATE, "it is not permitted while started");
 
+        abandonInternalFocus();
+
         int errorCode = SOUND_MANAGER_ERROR_NONE;
         CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
         char *type = NULL;
@@ -528,12 +572,12 @@ void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) throw(CAudioError)
         getAudioInfo().setAudioIndex(index);
 
         AUDIO_IO_LOGD("stream info(%p) is set", stream_info);
-    } catch (CAudioError e) {
-        throw e;
+    } catch (CAudioError& e) {
+        throw;
     }
 }
 
-void CAudioIO::setInternalStreamInfo() throw(CAudioError) {
+void CAudioIO::setInternalStreamInfo() {
     if (__mIsInit == false)
         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
 
@@ -548,7 +592,22 @@ void CAudioIO::setInternalStreamInfo() throw(CAudioError) {
             AUDIO_IO_LOGD("get internal VOIP stream info(%p)", stream_info);
             setStreamInfo(stream_info);
         }
-    } catch (CAudioError e) {
-        throw e;
+    } catch (CAudioError& e) {
+        throw;
+    }
+}
+
+void CAudioIO::abandonInternalFocus() {
+    bool isSkip = mpAudioSessionHandler->isSkipSession();
+    int id = mpAudioSessionHandler->getId();
+
+    try {
+        if (isSkip == false && id >= 0)
+            mpAudioSessionHandler->unregisterSound();
+
+        mpAudioSessionHandler->finalize();
+        __mForceIgnore = true;
+    } catch (CAudioError& e) {
+        throw;
     }
 }