From: Sangchul Lee Date: Thu, 5 Nov 2015 06:48:11 +0000 (+0900) Subject: Return error if APIs related to focus are called in the same thread with focus callback's X-Git-Tag: submit/tizen/20151105.120840^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F89%2F51189%2F2;p=platform%2Fcore%2Fapi%2Fsound-manager.git Return error if APIs related to focus are called in the same thread with focus callback's 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 --- diff --git a/include/sound_manager.h b/include/sound_manager.h index fb0a110..5aea42d 100644 --- a/include/sound_manager.h +++ b/include/sound_manager.h @@ -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 diff --git a/include/sound_manager_internal.h b/include/sound_manager_internal.h index a18b3a2..7d5955e 100644 --- a/include/sound_manager_internal.h +++ b/include/sound_manager_internal.h @@ -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() diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index eacef37..a7cf209 100755 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -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 diff --git a/src/sound_manager.c b/src/sound_manager.c index 6d69a96..cbe8b05 100644 --- a/src/sound_manager.c +++ b/src/sound_manager.c @@ -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); diff --git a/src/sound_manager_internal.c b/src/sound_manager_internal.c index 6e98f9f..7fc3840 100644 --- a/src/sound_manager_internal.c +++ b/src/sound_manager_internal.c @@ -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); diff --git a/src/sound_manager_private.c b/src/sound_manager_private.c index a6350b3..6de41f8 100644 --- a/src/sound_manager_private.c +++ b/src/sound_manager_private.c @@ -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; } diff --git a/test/sound_manager_test.c b/test/sound_manager_test.c index 69db7d5..6a58b74 100644 --- a/test/sound_manager_test.c +++ b/test/sound_manager_test.c @@ -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);