Return error of acquiring/releasing focus in focus watch callback when the previous... 20/202020/2 accepted/tizen/unified/20190325.070909 submit/tizen/20190322.072428
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 22 Mar 2019 01:44:43 +0000 (10:44 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 22 Mar 2019 03:50:22 +0000 (12:50 +0900)
[Version] 0.5.21
[Issue Type] Enhancement

Change-Id: Ic78f6f13024de8f604570f35ca5e28f8a07f3ee6
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/sound_manager_private.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
src/sound_manager_private.c

index 30aa35d0da40f4818d1c616d69d6fdc30323adac..1c72fc40cb7744613b5f00c2164c9885f97bd092 100644 (file)
@@ -199,6 +199,7 @@ typedef struct _sound_stream_info_s {
        int focus_id;
        char *stream_type;
        bool is_focus_unavailable;
+       bool is_requesting;
        pa_threaded_mainloop *pa_mainloop;
        pa_context *pa_context;
        stream_conf_info_s stream_conf_info;
index 9a02108a47e1a6fabf2e32f13a8b0a6f6017cef0..916073b75de67c5751651aae76962ade69a2d845 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.5.20
+Version:    0.5.21
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 626017f1bce46bd1658193ea4eb1cc568e203295..acbde74f67ef20a75a905ed73fd32286e9de7e70 100644 (file)
@@ -273,13 +273,14 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo
 {
        int ret = MM_ERROR_NONE;
        bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (stream_h->is_focus_unavailable) {
@@ -296,6 +297,12 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
                SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
        } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
        }
 
@@ -312,6 +319,8 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo
                goto LEAVE;
        }
 
+       stream_h->is_requesting = true;
+
        ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
                stream_h->acquired_focus |= focus_mask;
@@ -322,6 +331,7 @@ int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_fo
        LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
 
 LEAVE:
+       stream_h->is_requesting = false;
        SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
        if (!is_focus_cb_thread)
                SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
@@ -333,19 +343,26 @@ int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_fo
 {
        int ret = MM_ERROR_NONE;
        bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (!is_focus_cb_thread) {
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
                SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
        } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
        }
 
@@ -362,6 +379,8 @@ int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_fo
                goto LEAVE;
        }
 
+       stream_h->is_requesting = true;
+
        ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
                stream_h->acquired_focus &= ~focus_mask;
@@ -372,6 +391,7 @@ int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_fo
        LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
 
 LEAVE:
+       stream_h->is_requesting = false;
        SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
        if (!is_focus_cb_thread)
                SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
@@ -384,13 +404,14 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b
        int ret = MM_ERROR_NONE;
        int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
        bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (stream_h->is_focus_unavailable) {
@@ -407,6 +428,12 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
                SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
        } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
        }
 
@@ -424,6 +451,8 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b
                goto LEAVE;
        }
 
+       stream_h->is_requesting = true;
+
        ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
                stream_h->acquired_focus |= focus_mask;
@@ -432,6 +461,7 @@ int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_b
        }
 
 LEAVE:
+       stream_h->is_requesting = false;
        SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
        if (!is_focus_cb_thread)
                SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
@@ -443,19 +473,26 @@ int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_b
 {
        int ret = MM_ERROR_NONE;
        bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (!is_focus_cb_thread) {
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
                SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
        } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
                SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
        }
 
@@ -472,6 +509,8 @@ int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_b
                goto LEAVE;
        }
 
+       stream_h->is_requesting = true;
+
        ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
                stream_h->acquired_focus = 0;
@@ -480,6 +519,7 @@ int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_b
        }
 
 LEAVE:
+       stream_h->is_requesting = false;
        SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
        if (!is_focus_cb_thread)
                SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
@@ -524,7 +564,7 @@ int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h
        SM_INSTANCE_CHECK(src_stream_h);
        SM_INSTANCE_CHECK(dst_stream_h);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (is_focus_cb_thread) {
@@ -607,7 +647,7 @@ int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e
        SM_NULL_ARG_CHECK(acquired_by);
        SM_NULL_ARG_CHECK(flags);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (is_focus_cb_thread) {
@@ -645,7 +685,7 @@ int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e
        SM_NULL_ARG_CHECK(acquired_by);
        SM_NULL_ARG_CHECK(flags);
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
                return _convert_sound_manager_error_code(__func__, ret);
 
        if (is_focus_cb_thread) {
index 2fbc44c8bcd94bfbee8fdfa888642026ea4dca60..0258faf70695970166d5b98f419b9adc94a21172 100644 (file)
@@ -1910,7 +1910,7 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_
        int i = 0;
        bool is_focus_cb_thread = false;
 
-       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
                return ret;
 
        if (is_focus_cb_thread)
@@ -2008,7 +2008,7 @@ int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
        int ret = MM_ERROR_NONE;
        bool is_focus_cb_thread = false;
 
-       ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread);
+       ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL);
        if (ret)
                return ret;