Fix improper implementation of CPulseAudioClient::getReadableSize()
[platform/core/api/audio-io.git] / src / cpp / CPulseAudioClient.cpp
index 0676cb8..2b598d7 100644 (file)
@@ -18,6 +18,9 @@
 #include "CAudioIODef.h"
 #include <unistd.h>
 #include <inttypes.h>
+#include <string.h>
+#include <assert.h>
+#include <algorithm>
 
 #ifdef ENABLE_DPM
 #include <dpm/restriction.h>
@@ -31,8 +34,8 @@ using namespace tizen_media_audio;
  * class CPulseAudioClient
  */
 const char* CPulseAudioClient::CLIENT_NAME = "AUDIO_IO_PA_CLIENT";
-static const unsigned int drain_wait_interval = 10000;
-static const unsigned int drain_wait_max_count = 30;
+static constexpr unsigned int drain_wait_interval = 10000;
+static constexpr unsigned int drain_wait_max_count = 30;
 
 CPulseAudioClient::CPulseAudioClient(
         EStreamDirection      direction,
@@ -122,8 +125,8 @@ void CPulseAudioClient::__streamStateChangeCb(pa_stream* s, void* user_data) {
         pa_threaded_mainloop_signal(pClient->__mpMainloop, 0);
         break;
 
-    case PA_STREAM_FAILED:
 //LCOV_EXCL_START
+    case PA_STREAM_FAILED:
         AUDIO_IO_LOGD("The stream is failed");
         pClient->__mpListener->onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE,
                                               __is_microphone_restricted());
@@ -293,10 +296,7 @@ void CPulseAudioClient::initialize() {
             THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_proplist_new()"); //LCOV_EXCL_LINE
 
         // Adds values on proplist for delivery to PULSEAUDIO
-        char *streamType = nullptr;
-        CAudioInfo::EAudioType audioType = __mSpec.getAudioInfo().getAudioType();
-        __mSpec.getAudioInfo().convertAudioType2StreamType(audioType, &streamType);
-        pa_proplist_sets(__mpPropList, PA_PROP_MEDIA_ROLE, streamType);
+        pa_proplist_sets(__mpPropList, PA_PROP_MEDIA_ROLE, __mSpec.getAudioInfo().getConvertedStreamType());
 
         int index = __mSpec.getAudioInfo().getAudioIndex();
         if (index >= 0)
@@ -328,8 +328,10 @@ void CPulseAudioClient::initialize() {
 
         // Start mainloop
         if (pa_threaded_mainloop_start(__mpMainloop) < 0) {
+//LCOV_EXCL_START
             pa_threaded_mainloop_unlock(__mpMainloop);
-            THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed pa_threaded_mainloop_start()"); //LCOV_EXCL_LINE
+            THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed pa_threaded_mainloop_start()");
+//LCOV_EXCL_STOP
         }
 
         // Connection process is asynchronously
@@ -434,9 +436,11 @@ void CPulseAudioClient::initialize() {
         pa_threaded_mainloop_unlock(__mpMainloop);
 
         // __mIsInit = true;  // Moved to __streamStateChangeCb()
-    } catch (CAudioError& e) {
+    } catch (const CAudioError& e) {
+//LCOV_EXCL_START
         finalize();
         throw;
+//LCOV_EXCL_END
     }
 }
 
@@ -498,15 +502,15 @@ void CPulseAudioClient::finalize() {
 
 int CPulseAudioClient::read(void* buffer, size_t length) {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); //LCOV_EXCL_LINE
 
     checkRunningState();
 
     if (!buffer)
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The parameter is invalid : buffer[%p]", buffer);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The parameter is invalid : buffer[%p]", buffer); //LCOV_EXCL_LINE
 
     if (__mDirection == EStreamDirection::STREAM_DIRECTION_PLAYBACK)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function"); //LCOV_EXCL_LINE
 
     size_t lengthIter = length;
     int ret = 0;
@@ -522,7 +526,7 @@ int CPulseAudioClient::read(void* buffer, size_t length) {
             while (!__mpSyncReadDataPtr) {
                 ret = pa_stream_peek(__mpStream, &__mpSyncReadDataPtr, &__mSyncReadLength);
                 if (ret != 0)
-                    THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pa_stream_peek() : ret[%d]", ret);
+                    THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pa_stream_peek() : ret[%d]", ret); //LCOV_EXCL_LINE
 
                 if (__mSyncReadLength <= 0) {
 #ifdef _AUDIO_IO_DEBUG_TIMING_
@@ -530,19 +534,18 @@ int CPulseAudioClient::read(void* buffer, size_t length) {
 #endif
                     pa_threaded_mainloop_wait(__mpMainloop);
                 } else if (!__mpSyncReadDataPtr) {
+// LCOV_EXCL_START
                     // Data peeked, but it doesn't have any data
                     ret = pa_stream_drop(__mpStream);
                     if (ret != 0)
-                        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pa_stream_drop() : ret[%d]", ret); //LCOV_EXCL_LINE
+                        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pa_stream_drop() : ret[%d]", ret);
+//LCOV_EXCL_STOP
                 } else {
                     __mSyncReadIndex = 0;
                 }
             }
 
-            if (__mSyncReadLength < lengthIter)
-                l = __mSyncReadLength;
-            else
-                l = lengthIter;
+            l = min(__mSyncReadLength, lengthIter);
 
             // Copy partial pcm data on out parameter
 #ifdef _AUDIO_IO_DEBUG_TIMING_
@@ -575,10 +578,12 @@ int CPulseAudioClient::read(void* buffer, size_t length) {
 
         pa_threaded_mainloop_unlock(__mpMainloop);
         __mIsUsedSyncRead = false;
-    } catch (CAudioError& e) {
+    } catch (const CAudioError& e) {
+// LCOV_EXCL_START
         pa_threaded_mainloop_unlock(__mpMainloop);
         __mIsUsedSyncRead = false;
         throw;
+// LCOV_EXCL_STOP
     }
 
     return length;
@@ -586,15 +591,16 @@ int CPulseAudioClient::read(void* buffer, size_t length) {
 
 int CPulseAudioClient::peek(const void** buffer, size_t* length) {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
     if (!buffer || !length)
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The parameter is invalid : buffer[%p], length[%p]", buffer, length);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,                          // LCOV_EXCL_LINE
+                               "The parameter is invalid : buffer[%p], length[%p]", buffer, length); // LCOV_EXCL_LINE
 
     if (__mDirection == EStreamDirection::STREAM_DIRECTION_PLAYBACK)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function"); // LCOV_EXCL_LINE
 
     int ret = 0;
 
@@ -618,7 +624,7 @@ int CPulseAudioClient::peek(const void** buffer, size_t* length) {
 
 int CPulseAudioClient::drop() {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
 #ifdef _AUDIO_IO_DEBUG_TIMING_
     AUDIO_IO_LOGD("");
@@ -627,7 +633,7 @@ int CPulseAudioClient::drop() {
     checkRunningState();
 
     if (__mDirection == EStreamDirection::STREAM_DIRECTION_PLAYBACK)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function"); // LCOV_EXCL_LINE
 
     int ret = 0;
 
@@ -647,10 +653,10 @@ int CPulseAudioClient::drop() {
 
 int CPulseAudioClient::write(const void* data, size_t length) {
     if (!data)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The parameter is invalid");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The parameter is invalid"); // LCOV_EXCL_LINE
 
     if (__mDirection == EStreamDirection::STREAM_DIRECTION_RECORD)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function"); // LCOV_EXCL_LINE
 
     int ret = 0;
 
@@ -668,6 +674,7 @@ int CPulseAudioClient::write(const void* data, size_t length) {
         ret = pa_stream_write(__mpStream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
         pa_threaded_mainloop_unlock(__mpMainloop);
     } else {
+// LCOV_EXCL_START
         if (pa_stream_is_corked(__mpStream)) {
             AUDIO_IO_LOGW("stream is corked...do uncork here first!!!!");
             pa_operation_unref(pa_stream_cork(__mpStream, 0, NULL, this));
@@ -689,6 +696,7 @@ int CPulseAudioClient::write(const void* data, size_t length) {
                           length, prebuf, (length < prebuf) ? prebuf - length : 0);
         }
         ret = pa_stream_write(__mpStream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
+// LCOV_EXCL_STOP
     }
 
     if (ret < 0)
@@ -701,10 +709,10 @@ void CPulseAudioClient::cork(bool cork) {
     AUDIO_IO_LOGD("cork[%d]", cork);
 
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     if (isInThread())
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "This operation is not supported in callback");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "This operation is not supported in callback"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
@@ -723,7 +731,7 @@ void CPulseAudioClient::cork(bool cork) {
 
 bool CPulseAudioClient::isCorked() {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
@@ -745,7 +753,7 @@ bool CPulseAudioClient::isCorked() {
 
 bool CPulseAudioClient::drain() {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
@@ -786,7 +794,7 @@ bool CPulseAudioClient::drain() {
 
 bool CPulseAudioClient::flush() {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
@@ -805,12 +813,12 @@ bool CPulseAudioClient::flush() {
 
 size_t CPulseAudioClient::getWritableSize() {
     if (!__mIsInit)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient"); // LCOV_EXCL_LINE
 
     checkRunningState();
 
     if (__mDirection != EStreamDirection::STREAM_DIRECTION_PLAYBACK)
-        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "This client is used for Playback");
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "This client is used for Playback"); // LCOV_EXCL_LINE
 
     size_t ret = 0;
 
@@ -827,13 +835,16 @@ size_t CPulseAudioClient::getWritableSize() {
 
 void CPulseAudioClient::checkRunningState() {
     if (!__mpContext || !PA_CONTEXT_IS_GOOD(pa_context_get_state(__mpContext)))
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED, "The context[%p] is not created or not good state", __mpContext);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED,                       // LCOV_EXCL_LINE
+                               "The context[%p] is not created or not good state", __mpContext); // LCOV_EXCL_LINE
 
     if (!__mpStream || !PA_STREAM_IS_GOOD(pa_stream_get_state(__mpStream)))
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED, "The stream[%p] is not created or not good state", __mpStream);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED,                     // LCOV_EXCL_LINE
+                               "The stream[%p] is not created or not good state", __mpStream); // LCOV_EXCL_LINE
 
     if (pa_context_get_state(__mpContext) != PA_CONTEXT_READY || pa_stream_get_state(__mpStream) != PA_STREAM_READY)
-        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED, "The context[%p] or stream[%p] state is not ready", __mpContext, __mpStream);
+        THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_INITIALIZED,                                   // LCOV_EXCL_LINE
+                               "The context[%p] or stream[%p] state is not ready", __mpContext, __mpStream); // LCOV_EXCL_LINE
 
 #ifdef _AUDIO_IO_DEBUG_TIMING_
     AUDIO_IO_LOGD("This client is running");
@@ -866,7 +877,7 @@ size_t CPulseAudioClient::getReadableSize() {
         ret = pa_stream_readable_size(__mpStream);
         pa_threaded_mainloop_unlock(__mpMainloop);
     } else {
-        ret = pa_stream_writable_size(__mpStream);
+        ret = pa_stream_readable_size(__mpStream);
     }
 
     return ret;
@@ -897,7 +908,7 @@ size_t CPulseAudioClient::getBufferSize() {
             ret = attr->fragsize;
             AUDIO_IO_LOGD("RECORD buffer size[%zu]", ret);
         }
-    } catch (CAudioError& e) {
+    } catch (const CAudioError& e) {
         if (!isInThread())
             pa_threaded_mainloop_unlock(__mpMainloop);
         throw;
@@ -941,7 +952,7 @@ pa_usec_t CPulseAudioClient::getLatency() {
             /* Wait until latency data is available again */
             pa_threaded_mainloop_wait(__mpMainloop);
         }
-    } catch (CAudioError& e) {
+    } catch (const CAudioError& e) {
         pa_threaded_mainloop_unlock(__mpMainloop);
         throw;
     }
@@ -986,7 +997,7 @@ pa_usec_t CPulseAudioClient::getFinalLatency() {
 
         if (!isInThread())
             pa_threaded_mainloop_unlock(__mpMainloop);
-    } catch (CAudioError& e) {
+    } catch (const CAudioError& e) {
         if (!isInThread())
             pa_threaded_mainloop_unlock(__mpMainloop);
         throw;