Trigger stream state change callback when stream is failed/terminated and include...
[platform/core/api/audio-io.git] / src / cpp / CAudioIO.cpp
index fc3792f..d1898f7 100644 (file)
@@ -18,7 +18,6 @@
 #include <mm.h>
 #include <pthread.h>
 #include <assert.h>
-#include <audio-session-manager.h>
 #include "CAudioIODef.h"
 
 #define AUDIO_IO_DEBUG
@@ -33,17 +32,25 @@ using namespace tizen_media_audio;
 CAudioIO::CAudioIO() :
     mpAudioSessionHandler(NULL),
     mpPulseAudioClient(NULL),
+    __mMutex(PTHREAD_MUTEX_INITIALIZER),
+    __mCond(PTHREAD_COND_INITIALIZER),
     __mIsInit(false),
     __mForceIgnore(false) {
-    mState = CAudioInfo::AUDIO_IO_STATE_NONE;
-    mStatePrev = CAudioInfo::AUDIO_IO_STATE_NONE;
+    mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
+    mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mByPolicy = false;
 }
 
-CAudioIO::CAudioIO(CAudioInfo& audioInfo) : mpAudioSessionHandler(NULL), mpPulseAudioClient(NULL), __mIsInit(false), __mForceIgnore(false) {
+CAudioIO::CAudioIO(CAudioInfo& audioInfo) :
+    mpAudioSessionHandler(NULL),
+    mpPulseAudioClient(NULL),
+    __mMutex(PTHREAD_MUTEX_INITIALIZER),
+    __mCond(PTHREAD_COND_INITIALIZER),
+    __mIsInit(false),
+    __mForceIgnore(false) {
     mAudioInfo = audioInfo;
-    mState = CAudioInfo::AUDIO_IO_STATE_NONE;
-    mStatePrev = CAudioInfo::AUDIO_IO_STATE_NONE;
+    mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
+    mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
     mByPolicy = false;
 }
 
@@ -59,38 +66,38 @@ bool CAudioIO::isInit() {
 }
 
 bool CAudioIO::IsReady() {
-    return ((mState == CAudioInfo::AUDIO_IO_STATE_RUNNING || mState == CAudioInfo::AUDIO_IO_STATE_PAUSED)? true : false);
+    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() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     if (pthread_mutex_lock(&__mMutex) != 0) {
-        THROW_ERROR_MSG(CAudioError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
+        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);
 #endif
 }
 
-void CAudioIO::internalUnlock() throw (CAudioError) {
+void CAudioIO::internalUnlock() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     if (pthread_mutex_unlock(&__mMutex) != 0) {
-        THROW_ERROR_MSG(CAudioError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
+        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);
 #endif
 }
 
-void CAudioIO::internalWait() throw (CAudioError) {
+void CAudioIO::internalWait() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
 #ifdef _AUDIO_IO_DEBUG_TIMING_
@@ -100,9 +107,9 @@ void CAudioIO::internalWait() throw (CAudioError) {
     pthread_cond_wait(&__mCond, &__mMutex);
 }
 
-void CAudioIO::internalSignal() throw (CAudioError) {
+void CAudioIO::internalSignal() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
 #ifdef _AUDIO_IO_DEBUG_TIMING_
@@ -116,7 +123,7 @@ bool CAudioIO::isForceIgnore() {
     return __mForceIgnore;
 }
 
-void CAudioIO::initialize() throw (CAudioError) {
+void CAudioIO::initialize() throw(CAudioError) {
     if (__mIsInit == true) {
         return;
     }
@@ -125,12 +132,12 @@ void CAudioIO::initialize() throw (CAudioError) {
 
     int ret = pthread_mutex_init(&__mMutex, NULL);
     if (ret != 0) {
-        THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_init()");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_init()");
     }
 
     ret = pthread_cond_init(&__mCond, NULL);
     if (ret != 0) {
-        THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_init()");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_init()");
     }
 
     __mIsInit = true;
@@ -145,12 +152,12 @@ void CAudioIO::finalize() {
 
     int ret = pthread_mutex_destroy(&__mMutex);
     if (ret != 0) {
-        THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_destroy() ret:%d", ret);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_destroy() ret:%d", ret);
     }
 
     ret = pthread_cond_destroy(&__mCond);
     if (ret != 0) {
-        THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_destroy() ret:%d", ret);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_destroy() ret:%d", ret);
     }
 
     __mIsInit = false;
@@ -172,12 +179,15 @@ void CAudioIO::onStream(CPulseAudioClient* pClient, size_t length) {
 
 void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy) {
     assert(__mIsInit == true);
-    assert(state > 0);
+    assert(state >= CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE && state < CAudioInfo::EAudioIOState::AUDIO_IO_STATE_MAX);
 
     mStatePrev = mState;
     mState     = state;
     mByPolicy  = byPolicy;
 
+    if (mState == mStatePrev)
+        return;
+
     AUDIO_IO_LOGD("current(%d), previous(%d), by_policy(%d)", mState, mStatePrev, mByPolicy);
 
     if (mStateChangedCallback.onStateChanged != NULL) {
@@ -199,7 +209,7 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
         // Triggered by 'focus watch callback'
         ///////////////////////////////////////
 
-        if (session_option & (ASM_SESSION_OPTION_PAUSE_OTHERS | ASM_SESSION_OPTION_UNINTERRUPTIBLE)) {
+        if (session_option & (MM_SESSION_OPTION_PAUSE_OTHERS | MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
             AUDIO_IO_LOGD("Session option is pausing others or uninterruptible, skip...");
             return;
         }
@@ -209,7 +219,7 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
             internalLock();
 
             mpPulseAudioClient->cork(false);
-            onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING);
 
             internalUnlock();
 
@@ -219,14 +229,14 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
             // Focus handle(id) of the other application was acquired, do pause if possible
             internalLock();
 
-            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::STREAM_DIRECTION_PLAYBACK) {
+            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_PLAYBACK) {
                 if (mpPulseAudioClient->drain() == false) {
                     AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
                 }
             }
 
             mpPulseAudioClient->cork(true);
-            onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED);
 
             internalUnlock();
 
@@ -242,7 +252,7 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
             AUDIO_IO_LOGW("Id is different, why? [mId : %d]", pHandler->getId());
         }
 
-        if (session_option & ASM_SESSION_OPTION_UNINTERRUPTIBLE) {
+        if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
             AUDIO_IO_LOGD("Session option is uninterruptible, skip...");
             return;
         }
@@ -251,14 +261,14 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
             // Focus handle(id) was released, do pause here
             internalLock();
 
-            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::STREAM_DIRECTION_PLAYBACK) {
+            if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_PLAYBACK) {
                 if (mpPulseAudioClient->drain() == false) {
                     AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
                 }
             }
 
             mpPulseAudioClient->cork(true);
-            onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED);
 
             internalUnlock();
         } else if (state == FOCUS_IS_ACQUIRED) {
@@ -268,14 +278,14 @@ void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focu
             internalLock();
 
             mpPulseAudioClient->cork(false);
-            onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+            onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING);
 
             internalUnlock();
         }
     }
 
     if (mInterruptCallback.onInterrupt != NULL) {
-        IAudioSessionEventListener::EInterruptCode e = IAudioSessionEventListener::INTERRUPT_COMPLETED;
+        IAudioSessionEventListener::EInterruptCode e = IAudioSessionEventListener::EInterruptCode::INTERRUPT_COMPLETED;
         e = IAudioSessionEventListener::convertInterruptedCode(state, reason_for_change);
         mInterruptCallback.onInterrupt(e, mInterruptCallback.mUserData);
     }
@@ -295,9 +305,9 @@ void CAudioIO::onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t s
     }
 }
 
-void CAudioIO::prepare() throw (CAudioError) {
+void CAudioIO::prepare() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     try {
@@ -308,9 +318,9 @@ void CAudioIO::prepare() throw (CAudioError) {
     }
 }
 
-void CAudioIO::unprepare() throw (CAudioError) {
+void CAudioIO::unprepare() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     try {
@@ -321,9 +331,9 @@ void CAudioIO::unprepare() throw (CAudioError) {
     }
 }
 
-void CAudioIO::pause() throw (CAudioError) {
+void CAudioIO::pause() throw(CAudioError) {
     if (__mIsInit == false || IsReady() == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
 
     try {
@@ -337,9 +347,9 @@ void CAudioIO::pause() throw (CAudioError) {
     }
 }
 
-void CAudioIO::resume() throw (CAudioError) {
+void CAudioIO::resume() throw(CAudioError) {
     if (__mIsInit == false || IsReady() == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
 
     try {
@@ -353,9 +363,9 @@ void CAudioIO::resume() throw (CAudioError) {
     }
 }
 
-void CAudioIO::drain() throw (CAudioError) {
+void CAudioIO::drain() throw(CAudioError) {
     if (__mIsInit == false || IsReady() == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
 
     try {
@@ -369,9 +379,9 @@ void CAudioIO::drain() throw (CAudioError) {
     }
 }
 
-void CAudioIO::flush() throw (CAudioError) {
+void CAudioIO::flush() throw(CAudioError) {
     if (__mIsInit == false || IsReady() == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
     }
 
     try {
@@ -385,73 +395,73 @@ void CAudioIO::flush() throw (CAudioError) {
     }
 }
 
-CAudioInfo CAudioIO::getAudioInfo() throw (CAudioError) {
+CAudioInfo& CAudioIO::getAudioInfo() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     return mAudioInfo;
 }
 
-void CAudioIO::setStreamCallback(SStreamCallback callback) throw (CAudioError) {
+void CAudioIO::setStreamCallback(SStreamCallback callback) throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     mStreamCallback = callback;
 }
 
-CAudioIO::SStreamCallback CAudioIO::getStreamCallback() throw (CAudioError) {
+CAudioIO::SStreamCallback CAudioIO::getStreamCallback() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     return mStreamCallback;
 }
 
-void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) throw (CAudioError) {
+void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     mStateChangedCallback = callback;
 }
 
-CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() throw (CAudioError) {
+CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     return mStateChangedCallback;
 }
 
-void CAudioIO::setInterruptCallback(SInterruptCallback callback) throw (CAudioError) {
+void CAudioIO::setInterruptCallback(SInterruptCallback callback) throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     mInterruptCallback = callback;
 }
 
-CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() throw (CAudioError) {
+CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     return mInterruptCallback;
 }
 
 
-void CAudioIO::ignoreSession() throw (CAudioError) {
+void CAudioIO::ignoreSession() throw(CAudioError) {
     if (__mIsInit == false) {
-        THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
     }
 
     try {
         internalLock();
 
         if (mpPulseAudioClient != NULL && mpPulseAudioClient->isCorked() == false) {
-            THROW_ERROR_MSG(CAudioError::ERROR_INVALID_OPERATION, "An Operation is not permitted while started");
+            THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "An Operation is not permitted while started");
         }
 
         bool isSkip = mpAudioSessionHandler->isSkipSessionEvent();