Return error if APIs related to focus are called in the same thread with focus callback's 89/51189/2 accepted/tizen/mobile/20151106.045845 accepted/tizen/tv/20151106.045856 accepted/tizen/wearable/20151106.045910 submit/tizen/20151105.120840
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 5 Nov 2015 06:48:11 +0000 (15:48 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 5 Nov 2015 07:00:38 +0000 (16:00 +0900)
In that case, SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned. These APIs are as below.
 - sound_manager_create_stream_information()/sound_manager_destroy_stream_information()
 - sound_manager_acquire_focus()/sound_manager_release_focus()
 - sound_manager_set_focus_state_watch_cb()/sound_manager_unset_focus_state_watch_cb()

[Version] Release 0.3.24
[profile] Common
[Issue Type] Feature enhancement

Change-Id: Ib557ad0068ae9f06f8ac98f3f2614dbee10cb767

include/sound_manager.h
include/sound_manager_internal.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
src/sound_manager_internal.c
src/sound_manager_private.c
test/sound_manager_test.c

index fb0a110bb37635e6f79b3a52bee9d251d31fe583..5aea42dc27fedca64f5818b441cda1ab7a869c03 100644 (file)
@@ -521,10 +521,14 @@ int sound_manager_unset_volume_changed_cb(void);
  * @param[in]  user_data       The user data to be passed to the callback function
  * @param[out] stream_info     The handle of stream information
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_destroy_stream_information()
@@ -542,10 +546,14 @@ int sound_manager_create_stream_information(sound_stream_type_e stream_type, sou
  * @since_tizen 3.0
  * @param[in]  stream_info     The handle of stream information
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_create_stream_information()
  * @see sound_manager_add_device_for_stream_routing()
@@ -563,7 +571,7 @@ int sound_manager_destroy_stream_information(sound_stream_info_h stream_info);
  * @param[in]  stream_info     The handle of stream information
  * @param[in]  device          The device item from sound_device_list_h
  *
- * @remarks    @a Use sound_manager_get_current_device_list() and sound_manager_get_next_device() to get the device.\n
+ * @remarks    Use sound_manager_get_current_device_list() and sound_manager_get_next_device() to get the device.\n
  *     SOUND_MANAGER_ERROR_POLICY could be returned according to the stream type of the stream_info.\n
  *     The available type of the stream_info for this API is SOUND_STREAM_TYPE_VOIP.
  *
@@ -587,7 +595,7 @@ int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info,
  * @param[in]  stream_info     The handle of stream information
  * @param[in]  device          The device item from sound_device_list_h
  *
- * @remarks    @a Use sound_manager_get_current_device_list() and sound_manager_get_next_device() to get the device.\n
+ * @remarks    Use sound_manager_get_current_device_list() and sound_manager_get_next_device() to get the device.\n
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
@@ -607,7 +615,7 @@ int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_in
  * @since_tizen 3.0
  * @param[in]  stream_info     The handle of stream information
  *
- * @remarks    @a If the stream has not been made yet, this setting will be applied when the stream starts to play.\n
+ * @remarks    If the stream has not been made yet, this setting will be applied when the stream starts to play.\n
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
@@ -630,10 +638,14 @@ int sound_manager_apply_stream_routing(sound_stream_info_h stream_info);
  * @param[in]  focus_mask              The focus mask that user wants to acquire
  * @param[in]  additional_info Additional information for this request (optional, this can be null)
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INVALID_STATE Invalid state
  * @retval #SOUND_MANAGER_ERROR_POLICY Noncompliance with the sound system policy
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
@@ -652,10 +664,14 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo
  * @param[in]  focus_mask              The focus mask that user wants to release
  * @param[in]  additional_info Additional information for this request (optional, this can be null)
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INVALID_STATE Invalid state
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @pre Call sound_manager_create_stream_information()/sound_manager_acquire_focus() before calling this function.
@@ -711,12 +727,15 @@ int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *
  * @param[in]  callback        The focus state change watch callback function
  * @param[in]  user_data       The user data to be passed to the callback function
  *
- * @remarks    @a You can set this callback only once per process.
+ * @remarks    You can set this callback only once per process.
+ *     Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_unset_focus_state_watch_cb()
  */
@@ -726,9 +745,13 @@ int sound_manager_set_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask,
  * @brief Unregisters the focus state watch callback.
  * @since_tizen 3.0
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_set_focus_state_watch_cb()
  */
@@ -944,7 +967,7 @@ int sound_manager_unset_session_interrupted_cb(void);
  * @param[in]  device_mask     The mask value
  * @param[out] device_list     The list of connected devices
  *
- * @remarks    @a Use sound_manager_get_next_device() to get the first node of the list.
+ * @remarks    Use sound_manager_get_next_device() to get the first node of the list.
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
@@ -1105,7 +1128,7 @@ int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *
  * @param[in]  callback        The interrupted callback function
  * @param[in]  user_data       The user data to be passed to the callback function
  *
- * @remarks    @a The initial state of sound devices connected is deactivated.
+ * @remarks    The initial state of sound devices connected is deactivated.
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
index a18b3a292140c118f64a760ad81b18676b349d21..7d5955ed6f0194a93dde52f47cc636f8a4a4b88c 100644 (file)
@@ -78,10 +78,14 @@ typedef enum {
  * @param[in]  user_data       The user data to be passed to the callback function
  * @param[out] stream_info     The handle of stream information
  *
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.\n
+ *
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_destroy_stream_information()
  * @see sound_manager_add_device_for_stream_routing()
index eacef379eb76434e0be25513fad6bd698dd1aaea..a7cf209135c9cef832deffa2f60fbf183d70260f 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.3.23
+Version:    0.3.24
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 6d69a96b07857abb9b984e1a3d255b04e784f9f0..cbe8b052cbd32da11f36e7f15bceeba9d9628b57 100644 (file)
@@ -223,9 +223,11 @@ int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
 
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
        ret = _destroy_pa_connection_and_unregister_focus(stream_h);
-       free(stream_h);
-       stream_h = NULL;
-       SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret);
+       if (ret == MM_ERROR_NONE) {
+               free(stream_h);
+               stream_h = NULL;
+               SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret);
+       }
        SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
 
        LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret);
index 6e98f9fbfaee4024b3bf72d06a01b4b7f62a56d2..7fc38409cfcdea4766ff58305035a4f27fb3fe55 100644 (file)
@@ -41,6 +41,8 @@ int sound_manager_create_stream_information_internal(sound_stream_type_internal_
                                LOGI("<< leave : stream_h(%p), index(%u), user_cb(%p), ret(%p)", stream_h, stream_h->index, stream_h->user_cb, ret);
                        }
                }
+               if (ret)
+                       free(stream_h);
        }
 
        return _convert_sound_manager_error_code(__func__, ret);
index a6350b3232051f16f669fbc625cce98b38ed3d34..6de41f8b15081055f7d7fe3406a64a541e9965d6 100644 (file)
@@ -46,6 +46,7 @@ int _convert_sound_manager_error_code(const char *func, int code)
        switch (code) {
        case MM_ERROR_FILE_WRITE:
        case MM_ERROR_INVALID_HANDLE:
+       case MM_ERROR_SOUND_INVALID_OPERATION:
                ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
                errorstr = "INVALID_OPERATION";
                break;
@@ -83,7 +84,6 @@ int _convert_sound_manager_error_code(const char *func, int code)
                errorstr = "NO_PLAYING_SOUND";
                break;
        case MM_ERROR_NOT_SUPPORT_API:
-       case MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION:
                ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
                errorstr = "NOT_SUPPORTED";
                break;
@@ -1205,6 +1205,15 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_
        int ret = MM_ERROR_NONE;
        int pa_ret = PA_OK;
        int i = 0;
+       bool is_focus_cb_thread = false;
+
+       ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread);
+       if (ret)
+               return ret;
+       else {
+               if (is_focus_cb_thread)
+                       return MM_ERROR_SOUND_INVALID_OPERATION;
+       }
 
        if (!(stream_h->pa_mainloop = pa_threaded_mainloop_new()))
                goto PA_ERROR;
@@ -1302,7 +1311,6 @@ PA_ERROR:
                pa_threaded_mainloop_free(stream_h->pa_mainloop);
                stream_h->pa_mainloop = NULL;
        }
-       free(stream_h);
        ret = MM_ERROR_SOUND_INTERNAL;
        LOGE("pa_ret(%d), ret(%p)", pa_ret, ret);
 
@@ -1314,6 +1322,15 @@ int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
 {
        int i = 0;
        int ret = MM_ERROR_NONE;
+       bool is_focus_cb_thread = false;
+
+       ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread);
+       if (ret)
+               return ret;
+       else {
+               if (is_focus_cb_thread)
+                       return MM_ERROR_SOUND_INVALID_OPERATION;
+       }
 
        if (stream_h->pa_context) {
                pa_context_disconnect(stream_h->pa_context);
@@ -1580,7 +1597,7 @@ int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_strea
                        (*virtual_stream)->stream_info = stream_info;
                }
        } else
-               ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
+               ret = MM_ERROR_NOT_SUPPORT_API;
 
        return ret;
 }
index 69db7d5216f415913b2e51193669728701f05624..6a58b742092ad9770ccbdbfa2112e9728db5c6b9 100644 (file)
@@ -97,9 +97,13 @@ void focus_callback(sound_stream_info_h stream_info, sound_stream_focus_change_r
 
        if (playback_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED)
                g_print(" -- PLAYBACK_FOCUS acquired\n");
+       else
+               g_print(" -- PLAYBACK_FOCUS released\n");
 
        if (recording_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED)
                g_print(" -- FOCUS_RECORDING acquired\n");
+       else
+               g_print(" -- FOCUS_RECORDING released\n");
 
        g_print("*** FOCUS callback is ended, stream_info(%p) ****\n", stream_info);